Thread: Testing if a macro is defined to a value?

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    127

    Testing if a macro is defined to a value?

    Say I have something lke

    Code:
    #define FOO BAR
    
    #if FOO == BAR
      doX();
    #else
      doY();
    #endif
    This causes doX(); to be executed. But the intent is to have doY(); be run. I'm guessing this is because BAR is undefined and therefore blank, so blank equals blank. Is there some way to compare the symbol FOO was set to instead of its value, BAR?

  2. #2
    Lurker
    Join Date
    Dec 2004
    Posts
    296
    Quote Originally Posted by homer_3 View Post
    Say I have something lke

    Code:
    #define FOO BAR
    
    #if FOO == BAR
      doX();
    #else
      doY();
    #endif
    This causes doX(); to be executed. But the intent is to have doY(); be run. I'm guessing this is because BAR is undefined and therefore blank, so blank equals blank. Is there some way to compare the symbol FOO was set to instead of its value, BAR?
    Exactly what are you trying to to and what problem are you trying to solve with this?

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    127
    Quote Originally Posted by Jimmy View Post
    Exactly what are you trying to to and what problem are you trying to solve with this?
    Your standard cross-platform stuff. The API to do something on one platform isn't always the same as the API to do it on the other platform. So FOO is really more like PLATFORM and BAR is more like the name of that platform. Then in the code, if I'm using one platform I want to use one API, if not, use a different API.

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    This might do what you want to do.
    Un-tested code.
    Code:
    #if defined(BAR) && FOO == BAR
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  5. #5
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    The C preprocessor cannot compare strings, so the preprocessor itself cannot do this alone. (This is why the feature macros are always numbers; those can be compared using e.g. #if FOO == BAR in the preprocessor just fine.)

    However, if you use the C preprocessor to stringify the tokens, and compare them using strcmp(), most compilers are smart enough to do it at compile time (even without optimizations enabled, they should omit the string comparison call, and just emit code for one branch only).

    For example:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define DO_STRINGIFY(x) #x
    #define STRINGIFY(x) DO_STRINGIFY(x)
    
    int main(void)
    {
        printf("FOO = '%s'\n", STRINGIFY(FOO));
        printf("BAR = '%s'\n", STRINGIFY(BAR));
    
        if (!strcmp(STRINGIFY(FOO), STRINGIFY(BAR)))
            printf("strcmp(): FOO == BAR\n");
        else
            printf("strcmp(): FOO != BAR\n");
    
        return EXIT_SUCCESS;
    }
    If you compile this, it'll output strcmp(): FOO != BAR.

    If you examine the binary, you'll see there is no strcmp() call. Basically, the binary is what you'd get if this was done purely in the preprocessor. (None of my compilers need optimizations to be enabled to do this.)

    If you add #define FOO BAR, or define it during compilation, then it'll output strcmp(): FOO == BAR instead.

    If you define both FOO and BAR to the same value, even if you have no explicit #define FOO BAR, it'll correctly output strcmp(): FOO == BAR .

    Technically, the C preprocessor expands the macro, then stringifies the expansion, and in the code, the two immutable strings are compared using strcmp() (which the compiler can easily do at compile time). The reason you need two nested preprocessor macros is that the outer one expands the macro value, and the inner one convert the value to a string. If you use DO_STRINGIFY(FOO) alone, you'll just get the macro name stringified, i.e. "FOO".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overloading operator new when a macro new is defined
    By rjzak in forum C++ Programming
    Replies: 4
    Last Post: 03-30-2011, 03:57 PM
  2. Testing the value of an object-like macro
    By hzmonte in forum C Programming
    Replies: 3
    Last Post: 07-30-2008, 01:49 AM
  3. 64 bit testing
    By DrSnuggles in forum C++ Programming
    Replies: 7
    Last Post: 11-20-2007, 03:20 AM
  4. Testing Testing 123.. Oh yeah and...
    By minime6696 in forum Windows Programming
    Replies: 0
    Last Post: 08-13-2001, 09:07 AM