# Block expressions

> Syntax
> BlockExpression :
> `{`
> InnerAttribute*
> Statement*
> Expression?
> `}`

A block expression is similar to a module in terms of the declarations that are possible, but can also contain statements and end with an expression. Each block conceptually introduces a new namespace scope. Use items can bring new names into scopes and declared items are in scope for only the block itself.

A block will execute each statement sequentially, and then execute the expression, if given. If the block doesn't end in an expression, its value is `()`:

    # #![allow(unused_variables)]
    #fn main() {
    let x: () = { println!("Hello."); };
    #}

If it ends in an expression, its value and type are that of the expression:

    # #![allow(unused_variables)]
    #fn main() {
    let x: i32 = { println!("Hello."); 5 };

    assert_eq!(5, x);
    #}

Blocks are always value expressions and evaluate the last expression in value expression context. This can be used to force moving a value if really needed.

## `unsafe` blocks

> Syntax
> UnsafeBlockExpression :
> `unsafe` BlockExpression

See `unsafe` block for more information on when to use `unsafe`

A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers within a safe function. Examples:

    # #![allow(unused_variables)]
    #fn main() {
    unsafe {
        let b = [13u8, 17u8];
        let a = &b[0] as *const u8;
        assert_eq!(*a, 13);
        assert_eq!(*a.offset(1), 17);
    }

    # unsafe fn f() -> i32 { 10 }
    let a = unsafe { f() };
    #}

## Attributes on block expressions

Block expressions allow outer attributes and inner attributes directly after the opening brace when the block expression is the outer expression of an expression statement or the final expression of another block expression. The attributes that have meaning on a block expression are `cfg`, and the lint check attributes.

For example, this function returns `true` on unix platforms and `false` on other platforms.

    # #![allow(unused_variables)]
    #fn main() {
    fn is_unix_platform() -> bool {
        #[cfg(unix)] { true }
        #[cfg(not(unix))] { false }
    }
    #}