#include <stdio.h>
int main()
{
int sum = 0, result = (({for (int i = 0; i < 5; i++) sum += i;}), sum);
printf("result = %d\n", result);
return 0;
}
displays
result = 10
I'm using whatever the default version of C is in gcc. Is it specific to gcc? I'm aware (a, b)
returns b
but I didn't expect to get it to work when a
was a {}
block. Can anyone explain why it works and why the block has to be bracketed to get it to work?
EDIT: This is a contrived simplified example of a #define
I was trying out. Some programmer dude's comment (thanks) clears it up. Case closed.
I'm using whatever the default version of c is in gcc.
Currently that's -std=gnu17
, equivalent to "lax ISO C17 with GNU extensions". It is not a conforming mode and not recommended for beginners.
Is it specific to gcc?
Yes, or rather it is specific to the GNU C dialect, which is at least partially supported by clang as well. As mentioned in comments, this is a non-standard extension known as "statement expressions" or "statements in expressions". It allows multiple expressions/lines and optionally returns a value like a function-like macro.
I'm aware (a, b) returns b but I didn't expect to get it to work when a was a {} block
The comma operator has a special evaluation rule guaranteeing that the sub-expression a
is fully evaluated before b
. Normally this isn't the case with C operators. This means that you can assume that everything at a
is executed before b
and you may even safely include code using b
.
However, a list of variables to be initialized does not come with such a sequencing guarantee. int sum = 0, result=sum;
does not guarantee any particular order or sequencing - code such as this is deeply problematic and possibly undefined behavior.
Best practices are to follow standard C whenever possible, to write code as readable as possible and to avoid poorly-defined behavior. Complex "one-liner" code is very bad practice. So this would have been much better written as:
int sum = 0;
for (int i=0; i < 5; i++)
{
sum+=i;
}
int result = sum;
Or if you prefer, the 100% equivalent:
int result = 10;