6

Possible Duplicate:
Do-While and if-else statements in C/C++ macros

gcc (GCC) 4.7.2
c89

Hello,

I have the following function-like macro and just wondering what is the preferred usage when using across multiple lines. It it better to use curly braces or do..while(0) loop.

Normally I use a do..while(0) for everything. But I have seen some projects where they just use the curly braces, and I am not sure which one would be better.

do..while

#define DSO_ERROR(msg, res_handle_module, mem_pool, size)   do {        \
        char *dso_error = apr_palloc((apr_pool_t*)mem_pool, size);      \
        apr_dso_error((apr_dso_handle_t*)res_handle_module, (char*)dso_error, (apr_size_t)size); \
        LOG_ERR("%s dso error %s", (char*)msg, dso_error);              \
        goto dso_failure;                                               \
    } while(0); 

curly braces

#define DSO_ERROR(msg, res_handle_module, mem_pool, size) {             \
        char *dso_error = apr_palloc((apr_pool_t*)mem_pool, size);      \
        apr_dso_error((apr_dso_handle_t*)res_handle_module, (char*)dso_error, (apr_size_t)size); \
        LOG_ERR("%s dso error %s", (char*)msg, dso_error);              \
        goto dso_failure;                                               \
    }

The only difference is that a semi-colon will be preset on the do..while loop and not on the curly braces.

Many thanks for any suggestions,

Community
  • 1
  • 1
ant2009
  • 27,094
  • 154
  • 411
  • 609
  • 1
    My goodness, this is ugly code. (no offense intended, I'm just very surprised). – rubenvb Dec 07 '12 at 09:19
  • 4
    Adding the semicolon to the end of the `do { ... } while (0)` defeats the purpose of using `do { ... } while (0)` in the first place. The disadvantage of the braces-only version is that you cannot write `if (something) DSO_ERROR(...); else { ... }` because the semicolon is a null statement after the `if` and the `else` is a syntax error. With the corrected version of `do { ... } while (0)`, the `if` / `else` notation works as you'd expect if the macro were actually a function. – Jonathan Leffler Dec 08 '12 at 22:18

3 Answers3

8

The curly brace version will break usage like this:

if( foo )
  DSO_ERROR("Foo occured!", my_module, the_pool, 4711);
else
  printf("All is well, there is no foo\n");

which is the very reason for the do ... while(0) construct. So that seems worth avoiding.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 2
    As written by OP, the do...while(0) version will also break because it has an extra semicolon at the end. The right way to write the do...while(0) is without the semicolon. – Paolo Bonzini Dec 07 '12 at 11:16
4

you will have a problem with this code:

if (one) 
  DSO_ERROR("one", ...);
else
  DSO_ERROR("two", ...);

so if you use the do-while-Macro WITHOUT the semicolon, you would be fine.

Peter Miehle
  • 5,984
  • 2
  • 38
  • 55
2

Usually you do not have the semicolon on the do { ... } while (0) in the macro.

The reason you have do { ... } while (0) for the macro, is that then you can use the macro in the source and add a semicolon without there being an extra empty statement. This is mostly for historical reasons I guess, as having empty statements (i.e. just semicolons without any statements) doesn't do anything in many cases.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621