Skip to content

Clarify blocks being statements in doco #14640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -4034,7 +4034,7 @@ test "access variable after block scope" {
x += 1;
}
{#code_end#}
<p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used
<p>Blocks are statements, not expressions. When labeled, {#syntax#}break{#endsyntax#} can be used

This comment was marked as outdated.

This comment was marked as outdated.

Copy link
Contributor

@leecannon leecannon Feb 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not true that unlabelled blocks are always statements as they can be used on the right side on an assignment and result in a type of void

It is also not true that labelled blocks are always expressions, the label can be used only for break and continue control flow without any return value.

pub fn main() void {
    const a = {
        // this block is unlabelled but it is an expression and it evaluates to `void`
    };
    @compileLog(@TypeOf(a));

    blk: {
        // this block is labelled but is not an expression
        break :blk;
    }
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm very new to Zig so this may be a silly question, but is the block evaluating to void construct useful? Writing something like that seems like a mistake on the programmers side (and the compiler shouldn't allow it).

Also please take my comments with a grain of salt, I'm very new at Zig. Actually @zenspider was helping me try to understand why my if expression wasn't working, and it turned out to be due to the fact that blocks aren't expressions (IOW const x = if () { ... } is very different than const x = if () ..., and I didn't understand that)

Copy link
Contributor

@mitchellh mitchellh Feb 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm very new to Zig so this may be a silly question, but is the block evaluating to void construct useful? Writing something like that seems like a mistake on the programmers side (and the compiler shouldn't allow it).

Its the only way to initialize a void field. This is common practice in particular if you're using comptime to turn a field "on" or "off". i.e.:

const Widget = struct {
  const KnobType = if (builtin.target.isDarwin()) u64 else void;
  const knob_default = if (builtin.target.isDarwin()) 0 else {};

  knobs: KnobType = knob_default,
}

A void field takes up no space.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it is one of two ways to initialize a void value. The second way is the void literal 'void{}'.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm very new to Zig so this may be a silly question, but is the block evaluating to void construct useful? Writing something like that seems like a mistake on the programmers side (and the compiler shouldn't allow it).

Its the only way to initialize a void field. This is common practice in particular if you're using comptime to turn a field "on" or "off". i.e.:

const Widget = struct {
  const KnobType = if (builtin.target.isDarwin()) u64 else void;
  const knob_default = if (builtin.target.isDarwin()) 0 else {};

  knobs: KnobType = knob_default,
}

A void field takes up no space.

Awesome, this makes a lot of sense. Thank you for taking the time to explain, I really appreciate it!!

to return a value from the block:
</p>
{#code_begin|test|test_labeled_break#}
Expand Down