hANI
hANI

Reputation: 213

Mutiline macro statement that includes pre-processor directives

I am trying to define a macro which includes a pre-processor if-statement that checks the DEBUG state in its body. Essentially, here is what I would like to achieve:

Option 1

#define MY_MACRO  { \
                    #ifdef _DEBUG \
                         MyFunction(); \
                    #endif \
                  }

I know that an alternative implementation is the following:

Option 2

#ifdef _DEBUG
   #define MY_MACRO  MyFunction();
#else
   #define MY_MACRO
#endif

So, I have two questions:

  1. Is Option 1 above, correctly implemented? If not, what is the right way to do it?
  2. Is Option 2 always the preferred way to do this?

Upvotes: 0

Views: 92

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126243

There is no way to have a macro expand to any kind of preprocessor directive, so option 1 just won't work. The closest you can come is to define macro that has multiple definitions depending on ifdefs, as you've done in option 2. One thing you can do is define a macro that just expands to its arguments or to nothing, depending on ifdefs:

#ifdef _DEBUG
#define IF_DEBUG(...)    __VA_ARGS__
#else
#define IF_DEBUG(...)
#endif

Now you can use this macro in other macros:

#define MY_MACRO    IF_DEBUG( MyFunction() )

Upvotes: 1

Tony Delroy
Tony Delroy

Reputation: 106126

Yes, option two is the way to do this. As you probably discovered, option 1 just doesn't work. You should probably remove the trailing ; in the substitution though:

#define MY_MACRO  MyFunction()

Otherwise, if someone writes:

if (condition)
    MY_MACRO;
else
    do_something_else();

The substitution yields:

if (condition)
    MyFunction();;
else
    do_something_else();

...and the two semicolons tell the compiler that an if statement terminated and was followed by an empty statement, then there's an unexpected and illegal else.

Depending on the exact situation, it may be better to have:

#define MY_MACRO()  MyFunction()

So the calling code looks like:

MY_MACRO();

That's more consistent with a function call.

Upvotes: 1

Related Questions