Search code examples
cif-statementenumsc-preprocessorpreprocessor-directive

#if usage with enums


I have a header file with something like:

enum DataRate {
    AB0,
    AB1,
    AB2,
    ...
};

and in my code I have things like

#define S_FACTOR AB0

Now, function calls like

foo(S_FACTOR);

seem to work OK, but conditional compilations

#if ( (S_FACTOR == AB0) || (S_FACTOR == AB2) )

don't work properly.


Solution

  • The preprocessor knows nothing about enums; it is simply a manipulator of text. When you provide

    #define S_FACTOR AB0
    

    you are telling the preprocessor to substitute the token S_FACTOR with the token AB0, and nothing else.

    The #if preprocessor directive is a bit of an oddity. It still does little more than textual substitution, with the intent of reducing its argument to an arithmetic expression involving integer constants. So it starts by replacing all defined macros in the expression. Then it replaces any remaining identifier token with 0, and attempts to evaluate the expression.

    So

    #if ( (S_FACTOR == AB0) || (S_FACTOR == AB2) )
    

    will first be reduced to

    #if ( (AB0 == AB0) || (AB0 == AB2) )
    

    because S_FACTOR is a macro with a replacement list.

    Then it replaces all identifiers with 0:

    #if ( (0 == 0) || (0 == 0) )
    

    That certainly evaluates to 1 (by the usual C semantics for boolean values), so the body of the #if is processed. But it would have been exactly the same had S_FACTOR been #defined as AB1.

    There is a reason the preprocessor is called the preprocessor. It does its work before any other processing, including declarations.