23

If I do:

int j = ({int x = 7; x+3;});

In i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) gcc it compiles just fine. The block in question ({int x = 7; x+3;}) returns the value of the last statement as the value of the block. If you remove the parenthesis it doesn't compile. Can I expect this to work in most C compilers?

Additionally, what is the name for this construct? I have had a lot of trouble searching for it because search engines don't index () or {} and C is a terrible search term. I also haven't been able to find anything about it in any of my books, probably because I don't know what to look for.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jeff Plaisance
  • 233
  • 2
  • 5
  • 4
    Please don't expect it to work, and don't expect people to be able to read your code. – Puppe Oct 28 '09 at 07:00

3 Answers3

34

It's a GCC extension:

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.

Recall that a compound statement is a sequence of statements surrounded by braces; in this construct, parentheses go around the braces. For example:

 ({ int y = foo (); int z;
    if (y > 0) z = y;
    else z = - y;
    z; })

is a valid (though slightly more complex than necessary) expression for the absolute value of foo ().

The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct. (If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.)...

gnat
  • 6,213
  • 108
  • 53
  • 73
newacct
  • 119,665
  • 29
  • 163
  • 224
10

If you remove the parenthesis it doesn't compile.

Without the parentheses, the compiler will treat this as an aggregate initialization block and will fail when it sees the int keyword. You cannot have keywords in initializer blocks.

6.7.8 Initialization

11 The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.

6.2.5 Types

21 Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called aggregate types.


Can I expect this to work in most c compilers?

No. Looks like a non-standard GNU extension.

Additionally, what is the name for this construct?

I wonder if there is any. Actually, this is similar to what macros typically do.

ruakh
  • 175,680
  • 26
  • 273
  • 307
dirkgently
  • 108,024
  • 16
  • 131
  • 187
7

You can expect it to work in most versions of GCC.

You can expect it to work almost nowhere else - it is a GCC extension.

The section of the GCC manual that describes the feature is titled 'Statements and Declarations in Expressions':

A compound statement enclosed in parentheses may appear as an expression in GNU C.

Later it says:

Any temporaries created within a statement within a statement expression will be destroyed at the statement’s end. This makes statement expressions inside macros slightly different from function calls.

So, 'statement expression' seems to be the name used in the documentation.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • clang seems to support this too. – xiay Oct 01 '17 at 00:27
  • Clang supports most things that GCC supports for compatibility with GCC. That doesn' t make it a good idea, necessarily, to use it. You'll have to choose whether it is sensible or not. – Jonathan Leffler Oct 01 '17 at 01:03
  • Was just stating facts. Clang is not "almost nowhere" IMHO. No subjective comment on whether it is a good idea to use it. – xiay Oct 01 '17 at 01:15
  • Clang is 'just GCC in disguise' on this issue — even though the internals are completely different. If it weren't for GCC supporting it, I'm not sure that Clang would, though that's at best a semi-informed speculative guess, and impossible to verify either way since it is supported. AFAIAC, it is still a GCC extension. It's up to you whether you decide to use it. I've coded for 30 years without statement expressions, and have no particular plans to use it in the next 30, but will consider what's appropriate when it becomes necessary to do so. – Jonathan Leffler Oct 01 '17 at 01:19