C++ faq 38.5 - macros with multiple statements

Discussion in 'C++' started by Erik Haugen, Jan 8, 2004.

  1. Erik Haugen

    Erik Haugen Guest

    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
     
    Erik Haugen, Jan 8, 2004
    #1
    1. Advertising

  2. Erik Haugen

    David Fisher Guest

    "Erik Haugen" <> 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
     
    David Fisher, Jan 8, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    80
    Views:
    2,536
    Stephen J. Bevan
    Nov 7, 2003
  2. Replies:
    1
    Views:
    497
    Marco Antoniotti
    Oct 7, 2003
  3. Replies:
    5
    Views:
    516
  4. Michael T. Babcock

    Re: Explanation of macros; Haskell macros

    Michael T. Babcock, Nov 3, 2003, in forum: Python
    Replies:
    0
    Views:
    543
    Michael T. Babcock
    Nov 3, 2003
  5. Andrew Arro

    macros-loop? calling macros X times?

    Andrew Arro, Jul 23, 2004, in forum: C Programming
    Replies:
    2
    Views:
    520
    S.Tobias
    Jul 24, 2004
Loading...

Share This Page