Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C preprocessor with if statement

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?

like image 935
dimba Avatar asked Sep 28 '10 07:09

dimba


People also ask

What is conditional preprocessor?

A preprocessor conditional compilation directive causes the preprocessor to conditionally suppress the compilation of portions of source code.

What is preprocessor in C with example?

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 # .

Which is a conditional pre processing macro?

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.

Can you use Elif in C?

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).


2 Answers

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.

like image 150
Michael Burr Avatar answered Nov 15 '22 10:11

Michael Burr


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.

like image 20
ptomato Avatar answered Nov 15 '22 10:11

ptomato