56

Possible Duplicate:
#ifdef inside #define

How do I use the character "#" successfully inside a Macro? It screams when I do something like that:

#define DO(WHAT)        \
#ifdef DEBUG        \                           
  MyObj->WHAT()         \       
#endif              \
Community
  • 1
  • 1
JasonGenX
  • 4,952
  • 27
  • 106
  • 198

5 Answers5

72

You can't do that. You have to do something like this:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT) do { } while(0)
#endif

The do { } while(0) avoids empty statements. See this question, for example.

Community
  • 1
  • 1
Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380
  • So with an empty statement I could run into trouble on some c++ compilers? My app is cross platform, OSX, Windows and Ubuntu. Is this the safe thing to do? – JasonGenX Aug 30 '11 at 16:35
  • 2
    +1: The `do {} while(0)` construct is something I forgot to mention in my answer. – Oliver Charlesworth Aug 30 '11 at 16:40
  • @Ron: This actually lets you write : `if(x) DO(m); else DO(n);`. while @Oli's solution will give compilation error. – Nawaz Aug 30 '11 at 16:40
  • 3
    This is one reason to use inline functions rather than macros! – Bo Persson Aug 30 '11 at 16:43
  • 1
    @Bo Persson: What solution do you suggest using inline functions? Please post. – Nawaz Aug 30 '11 at 16:46
  • DO(m) and DO(n) can easily be function calls. Why bother with tricky macros? – Bo Persson Aug 30 '11 at 16:49
  • 1
    Well, in this case, `MyObj` would have to be passed as an argument to those functions, so it's not a drop in replacement. Moreover, you'd then have to mess about with pointer-to-member parameters, which could get ugly quite quickly. That said, I don't actually like this use of macros to hide what's going on, but the question was asked... – Roger Lipscombe Aug 31 '11 at 08:34
  • what about simply `#define DO(WHAT) ;` in the #else branch? – Kristóf Szalay Jun 09 '17 at 13:10
13

It screams because you can't do that.

I suggest the following as an alternative:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
5

It seems that what you want to do can be achieved like this, without running into any problems:

#ifdef DEBUG
#    define DO(WHAT) MyObj->WHAT()
#else
#    define DO(WHAT) while(false)
#endif

Btw, better use the NDEBUG macro, unless you have a more specific reason not to. NDEBUG is more widely used as a macro that means no-debugging. For example the standard assert macro can be disabled by defining NDEBUG. Your code would become:

#ifndef NDEBUG
#    define DO(WHAT) MyObj->WHAT()
#else
#    define DO(WHAT) while(false)
#endif
Paul Manta
  • 30,618
  • 31
  • 128
  • 208
2

You can do the same thing like this:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
antlersoft
  • 14,636
  • 4
  • 35
  • 55
2

How about:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152