I have the following macro:
#define IF_TRACE_ENABLED(level) if (IsTraceEnabled(level))
The user code should look following:
IF_TRACE_ENABLED(LEVEL1)
{
... some very smart code
}
The emphasis here on curly brackets - I want to prevent "if" from macro to "eat" other code:
if (...)
IF_TRACE_ENABLED(LEVEL1)
printf(....);
else
bla bla bla
In this example IF_TRACE_ENABLED
"eats" else block.
Is there way to enforce user code not compile without curly brakes or there are other to define the macro to achieve the safety?
A preprocessor conditional compilation directive causes the preprocessor to conditionally suppress the compilation of portions of source code.
Preprocessing directives are lines in your program that start with # . The # is followed by an identifier that is the directive name. For example, #define is the directive that defines a macro. Whitespace is also allowed before and after the # .
The conditional directives are: #ifdef - If this macro is defined. #ifndef - If this macro is not defined. #if - Test if a compile time condition is true.
The elif preprocessor directive in C is equivalent to an else if statement – it provides an alternate path of action when used with #if , #ifdef , or #ifndef directives. Execution enters the #elif block when the #if condition is false and the elif condition holds true (this is shown below).
This doesn't force the user of the macro to use braces, but it will prevent an else
clause from being unintentionally eaten:
#define IF_TRACE_ENABLED(level) if (!IsTraceEnabled(level)) {} else
A side note: braces around the printf()
in the second example of the question wouldn't have fixed the problem - the else
associated with bla bla bla
would still be bound to the if
statement in the macro.
You could try this:
#define IF_TRACE_ENABLED(level) do { if(IsTraceEnabled(level)) {
#define END_TRACE_ENABLED } } while(0);
I don't think there's any way to "enforce" good syntax from only the opening line of the macro. You will need to use two.
EDIT
I've added an extra pair of braces inside the macro to avoid all ambiguity.
In response to the comment, this macro is meant to be used like this:
IF_TRACE_ENABLED(LEVEL1)
printf("Trace\n");
END_TRACE_ENABLED
Not as a statement. For the record, I think this is an abuse of the preprocessor and nobody should do this at all. What's wrong with just writing it out, bracketed with #ifdef DEBUG
if necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With