Is #if defined MACRO equivalent to #ifdef MACRO?

后端 未结 5 1134
自闭症患者
自闭症患者 2020-12-08 21:38

I have code that I want to have two modes, debug and verbose. I define them in my header file as,

#define verbose TRUE
#def         


        
相关标签:
5条回答
  • 2020-12-08 21:42

    If we rack our brains enough, we can come up with a difference. But it is obscure and involves undefined behavior, so it is of no consequence if all we care about is whether the code is strictly conforming to ISO C.

    The #if defined ... form is susceptible to behaving differently if previously a #define defined ... macro was processed. In the ISO C99 standard it was written, in regard to the #if and #elif directives:

    Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text.

    No requirement is given that the defined unary operator be recognized and protected from being treated as a macro; it is just one of the "preprocessing tokens that will become the ... expression". The defined operator is recognized at this stage only for the purposes of protecting its argument from expansion.

    If the definition of define as a macro is simply permitted to stand, and occurrences of defined are subsequently replaced (including in the arguments of #if preprocessing directives) thus interfering with #if defined, while not affecting #ifdef.

    Perhaps this area of the language was tightened up since C99.

    0 讨论(0)
  • 2020-12-08 21:56

    #if defined(MACRO) is the same as #ifdef MACRO, but is longer. On the other hand it allows to add extra conditions with || or &&.

    #if MACRO is similar to #ifdef MACRO but not 100%. If MACRO is 0 then #if MACRO will be negative - it requires MACRO to be defined and not be 0. #ifdef checks only whether it is defined even without value (#define MACRO).

    Now is modern to use #if and enable/disable definitions with value 1 or 0:

    #define FLAG_X 1 // or 0

    0 讨论(0)
  • 2020-12-08 21:57

    If I'm reading your question correctly the title is misleading, it should be

    Is #if MACRO equivalent to #ifdef MACRO?
    

    They are not equivalent but they can (and often are) both used to specify binary modes which are either on or off. The choice is, in my opinion, a matter of personal preference.

    You are using the first option and either have

    #define verbose true
    

    or

    #define verbose false
    

    and then check the mode using either

    #if verbose
    

    or

    #if !verbose
    

    Actually, I would recommend you use either TRUE or 1 instead of true and either FALSE or 0 instead of false, because true and false, are (or can be) C/C++ values and the pre-processor doesn't have access to C/C++ values.

    Anyway, the other common way to specify binary modes is to either define the flag or leave it undefined in which case you can have either

    #define verbose any thing (including nothing) goes here
    

    or leave out the #define.

    and then you can test whether the flag is defined, either with

    #ifdef verbose
    

    or its equivalent

    #if defined(verbose)
    

    NOTE: In this case, you are not testing the value of the flag you only need to test whether it is defined.

    If it is more convenient you can also test whether the flag is undefined with either

    #ifndef verbose
    

    or its equivalent

    #if !defined(verbose)
    
    0 讨论(0)
  • 2020-12-08 22:01

    No, they are not at all equivalent. An #if MACRO branch is compiled if MACRO evaluates to non-zero. On the other hand, an #ifdef MACRO branch is compiled if MACRO is defined, no matter what it evaluates to. So

    #include <stdio.h>
    
    #define VAR_SET_TO_TRUE 1
    #define VAR_SET_TO_FALSE 0
    
    int main()
    {
    
    #if VAR_SET_TO_TRUE
        printf("#if VAR_SET_TO_TRUE\n");
    #endif
    
    #if VAR_SET_TO_FALSE
        printf("#if VAR_SET_TO_FALSE\n");
    #endif
    
    #if VAR_UNSET
        printf("#if VAR_UNSET\n");
    #endif
    
    
    
    #ifdef VAR_SET_TO_TRUE
        printf("#ifdef VAR_SET_TO_TRUE\n");
    #endif
    
    #ifdef VAR_SET_TO_FALSE
        printf("#ifdef VAR_SET_TO_FALSE\n");
    #endif
    
    #ifdef VAR_UNSET
        printf("#ifdef VAR_UNSET\n");
    #endif
    
    }
    

    will output

    #if VAR_SET_TO_TRUE
    #ifdef VAR_SET_TO_TRUE
    #ifdef VAR_SET_TO_FALSE
    

    Note that the line printf("#ifdef VAR_SET_TO_FALSE\n"); is compiled while the line printf("#if VAR_SET_TO_FALSE\n"); is not. The first one is compiled, because VAR_SET_TO_FALSE is defined, even though its value is false.

    0 讨论(0)
  • 2020-12-08 22:02
    #ifdef MACRO
    #if defined (MACRO)
    

    will do the exact same thing. However, the defined (MACRO) is just an expression that evaluates to 0 or 1 inside the #if, and it can be combined with other expressions. For example

    #if defined (MACRO) && ! defined (MACRO2)
        // Do this
    #else
        // Do that
    #endif
    

    Try doing that with #ifdef - you can't unless your code gets really clumsy.

    0 讨论(0)
提交回复
热议问题