6

Often, in macros, you will see people use a do { ... } while(0) to swallow the semicolon. I just came across an example where they use ({ ... }) instead, and it seems to not only swallow the semicolon, but seems to allow you to return a value as well:

#define NEW_MACRO()  ({ int x = 1; int y = 2; x+y; })

 if(1) 
   val = NEW_MACRO(); 
 else 
   printf("this never prints");`

val would come out being 3. I can't find any documentation on it, so I'm a bit wary of it. Are there any gotcha's with this method?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
John Ulvr
  • 636
  • 1
  • 8
  • 8

3 Answers3

10

This is not valid in standard C.

Some compilers may have extensions (e.g. GCC's statement expressions) that allow this sort of thing.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 1
    This particular notation, `({ ... })`, was invented by GCC as far as I know (it dates back at least as far as the very widely used GCC 2.7.2.3) and has only been picked up by compilers wishing to be compatible with GCC's extensions, such as Intel's proprietary compilers for Linux. – zwol Mar 23 '11 at 18:27
  • 1
    +1 It's also a twisted way of obscuring code, and making debugging harder :) – salezica Mar 23 '11 at 18:27
2

As Oli said correctly this was invented by gcc. The goal is (often with their typeof extension) to be able to evaluated macro elements only once and use this computed value later on by using a name.

Many times such a use can be completely avoided by using inline functions. These also have the (dis)advantage of being more strict on types.

In some other cases where you just need a temporary variable whose address you pass to a function, C99 also has compound literals that can be used for this.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

do { ... } while(0) is not for the "swallowing the semicolon". It is for turning the C expression to the C statement.

Alexander Poluektov
  • 7,844
  • 1
  • 28
  • 32
  • 3
    No, it's for turning a C block into a C statement, so that it behaves like a single "function call" in the presence of enclosing `if`/`else` and `do`/`while` statements. – R.. GitHub STOP HELPING ICE Mar 23 '11 at 19:55
  • @R it's *for* whatever the user uses it for. I've seen it used *for* swallowing the semi-colon also it also has the effect you describe. – Sam Liddicott Feb 16 '17 at 17:24