Search code examples
macrosc-preprocessorpreprocessor-directive

Is there a way to check for non-numeric value of a macro


Suppose I have

#define Name Joe

Is there a way to distinguish different values for the macro. The following does not work, but you get the idea

#if   Name==Joe
// some code
#elif Name==Ben
// some alternative code
#endif

I want to use this to generated various object files from the same source code. The source differs only little, so can easily be macro controlled. The macro is to be passed in via the -DName=Joe compiler flag. Note also that the Name will be an actual symbol name, so we cannot use tricks based on #define Joe 1 etc.


forced edit Note that this similar question actually deals with string-valued macros. Moreover the answers there don't help. The accepted answer avoids the problem (but doesn't solve it), another answer uses strcmp in the macros, which relies on an extension, etc.


Solution

  • Yes, it's possible, but it's not all that pretty.

    Here's an example; change NAME and it will print the correct thing. You just need to define TEST_FOR_Name ahead of time for each name, giving each a unique value.

    #define TEST_FOR_Joe 1
    #define TEST_FOR_Ben 2
    #define DO_TEST(NAME1, NAME2) DO_TEST_impl(NAME1, NAME2)
    #define DO_TEST_impl(NAME1, NAME2) TEST_FOR_ ## NAME1 == TEST_FOR_ ## NAME2
    
    #define NAME Ben
    
    #include <iostream>
    
    int main() {
      std::cout << "Hello!" << std::endl;
    #if DO_TEST(NAME, Joe)
      std::cout << "Joe Found!" << std::endl;
    #elif DO_TEST(NAME, Ben)
      std::cout << "Ben Found!" << std::endl;
    #else
      std::cout << "Neither found!" << std::endl;
    #endif
    }
    

    The basic idea is that we build tokens with unique numeric values associated with each name. If it can't find a value for the token, the comparison simply fails, but otherwise it makes sure that the numbers are the same.