How does "()" convert statements into expressions in C++? [duplicate]
Asked Answered
C

1

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?

Chauffeur answered 13/9, 2018 at 11:56 Comment(0)
O
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.

Oho answered 13/9, 2018 at 11:59 Comment(6)
Not to be confused with an expression statement, which is a standard thing.Oskar
With not a lot more furniture you could probably use a c++11 standard lambda expression to the same effect.Valletta
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?Klinger
@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.Pigeonhole
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.Armenta
@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.Amidst

© 2022 - 2024 — McMap. All rights reserved.