Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 794
Walter Avatar asked Oct 07 '15 17:10

Walter


1 Answers

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.

like image 145
Charles Ofria Avatar answered Oct 20 '22 00:10

Charles Ofria