Browsing the Linux kernel sources I found some piece of code where a block of statements surrounded by parenthesis is treated as a expression a la lisp (or ML), that is, an expression which value is the value of the last statement.
For example:
int a = ({
int i;
int t = 1;
for (i = 2; i<5; i++) {
t*=i;
}
t;
});
I've been looking at the ANSI C grammar trying to figure out how this piece of code would fit in the parse tree, but I haven't been successful.
So, does anybody know if this behaviour is mandated by the standard or is just a peculiarity of GCC?
Update: I've tried with the flag -pedantic and the compiler now gives me a warning:
warning: ISO C forbids braced-groups within expressions
It's called "braced-group within expression".
It's not allowed by ANSI/ISO C nor C++ but gcc supports it.
This is not valid C it is a
gcc
extension called statement expressions, you can find the complete list of C extensions here. This is actually one of the many gcc extensions used in the Linux kernel and it seems like clang supports this too and although it is not explicitly named in the document.As you observed the last expression serves as the value of the expression, the document says(emphasis mine):
One of the main benefits would be to make safe macros that would avoid multiple evaluations of arguments with side effects. The example given uses this unsafe macro:
which evaluates either
a
orb
twice and can be rewritten to eliminate this problem using statement expressions as follows:Note, the need to explicitly use
int
which can fixed using anothergcc
extension Typeof:Note that clang also supports typeof.