21

I have the following code:

int main() {
    int i=0;
    int j=({int k=3;++i;})+1; // this line
    return 0;
}

It compiles and runs. If I remove the () from "this line", then it doesn't compile.

I'm just curious what syntax rule is being applied here.

The {} contains 2 statements, and the last statement indicates the "return" value of this code block. Then why does it need an extra () pair to make this return value usable?

scopchanov
  • 7,966
  • 10
  • 40
  • 68
Hind Forsum
  • 9,717
  • 13
  • 63
  • 119

1 Answers1

36

That's a statement expression, and it's a GCC-specific extension.


From the linked reference:

A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression.

A compound statement is a curly-brace enclosed block of statements.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 8
    Not to be confused with an expression statement, which is a standard thing. – eerorika Sep 13 '18 at 12:03
  • 1
    With not a lot more furniture you could probably use a c++11 standard lambda expression to the same effect. – Gem Taylor Sep 13 '18 at 12:42
  • 1
    I doubt the link will die but would you mind quoting what it points to in your answer so you can get the information all in one place? – NathanOliver Sep 13 '18 at 12:49
  • @GemTaylor for that reason I think most C++ compilers don't support this extension: there's no point adding it to the language now, so it's pretty much deprecated in GNU C++. For C, the situation is more flexible as no lambda syntax has been standardized yet so this extension is more useful there. As the wording of the documentation hints, GCC expects this extension to be used mostly from C, not so much from C++; it's available from C++ anyway because G++ is permissive about that kind of thing. – Alex Celeste Sep 13 '18 at 13:59
  • 1
    Adding to what @Leushenko wrote: In C, statement expressions are dead useful for writing function-call like macros. It allows the macro to define its own variables in its own scope, and still "return" a value from the macro. The later is not possible with the other common workaround, which encloses the macro body in a `do{ ... } while (0)` loop. – cmaster - reinstate monica Sep 13 '18 at 14:13
  • @cmaster: In the days before C89, gcc included a number of features that really should have been included then. Some like anonymous structs and unions did get added 22 years later, but it irks me that the Standard takes the attitude that if some implementations might have difficulty with something, none should do it, instead of saying that implementations should support certain constructs if practical, but need not support them if impractical, and let the marketplace decide what features programmers end up demanding. – supercat Sep 13 '18 at 15:12