C++ faq 38.5 - macros with multiple statements

  • Follow


This item in the C++ faq:
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-38.5

discusses macros with multiple statements.

The problem is that a macro such as 

#define MYMACRO(a,b) stmt1; stmt2;

will cause unwanted astonishment if you say:

while(whatever)
   MYMACRO(foo,bar);


This is also problematic:

#define MYMACRO(a,b)  {stmt1; stmt2;}

because this won't compile:
if(foo())
   MYMACRO(i,j);
else
   baz();

since you can't have "}; else"


so the faq proposes this solution:

-------------
 #define MYMACRO(a, b) \ 
     if (true) { \ 
         statement1; \ 
         statement2; \ 
         ... \ 
         statementN; \
     } else 
-------------

But this seems like a bad solution; what if you write this:

MYMACRO(foo,bar) // note no semicolon
baz();

it compiles fine, but baz() *never* gets called!

Is there a way to avoid this?  Maybe the do/while idiom should be used
dispite the inlining problems?

// compiler may not inline functions that use this because of the loop...
 #define MYMACRO(a, b) \  
     do { \
         statement1; \
         statement2; \
         ... \
         statementN; \
     } while (false) 

thanks,
Erik

0
Reply haugen (2) 1/8/2004 10:40:03 AM

"Erik Haugen" <haugen@Xenon.Stanford.EDU> wrote:

> This item in the C++ faq:
> http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-38.5
>
> discusses macros with multiple statements.

[snip]

> the faq proposes this solution:
>
> -------------
>  #define MYMACRO(a, b) \
>      if (true) { \
>          statement1; \
>          statement2; \
>          ... \
>          statementN; \
>      } else
> -------------
>
> But this seems like a bad solution; what if you write this:
>
> MYMACRO(foo,bar) // note no semicolon
> baz();
>
> it compiles fine, but baz() *never* gets called!
>
> Is there a way to avoid this?  Maybe the do/while idiom should be used
> dispite the inlining problems?

How about this:

#define MYMACRO(a, b) \
     if (true) { \
         statement1; \
         statement2; \
     } else true

This makes the null statement explicit, and should cause a syntax error if
no semi colon follows (if this looks weird to anyone, an expression that
does nothing like "true" or "1+3" is a valid statement in C++).

The following cases mentioned in the FAQ should work OK:

while (whatever)
     MYMACRO(foo, bar);

if (whatever)
     MYMACRO(foo, bar);
else
     baz;

And there will be a (possibly obscure !) syntax error if the semi colon is
missing, as in your example:

MYMACRO(foo,bar) // note no semicolon
baz();

- because it will expand to "true baz()" at the end.

The reason for using "true" as the null statement and not "0" is because
there is less chance of the statement still being valid without a semi
colon, eg. something beginning with "-" or "*".

Hope this helps - let me know if I've missed something !

David F




0
Reply nospam5096 (66) 1/8/2004 10:53:13 PM


1 Replies
36 Views

(page loaded in 0.053 seconds)

Similiar Articles:













7/30/2012 3:33:04 AM


Reply: