8

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.

Community
  • 1
  • 1
Walter
  • 44,150
  • 20
  • 113
  • 196
  • 1
    Does a function not work for you? What is the use case for this? – NathanOliver Oct 07 '15 at 17:51
  • 3
    You likely do not want that (XY-problem) –  Oct 07 '15 at 17:52
  • @NathanOliver see edit – Walter Oct 07 '15 at 17:55
  • 5
    instead of defining name with a value why not just `#define Joe` and then you can check if `Joe` exist with `#if defined(Joe)` – NathanOliver Oct 07 '15 at 17:59
  • 2
    Numbers: Yes. Names: Not so much. – user3386109 Oct 07 '15 at 18:20
  • 2
    Possible duplicate of [how to compare string in C conditional preprocessor-directives](http://stackoverflow.com/questions/2335888/how-to-compare-string-in-c-conditional-preprocessor-directives) (although that question is about C only) – PC Luddite Oct 07 '15 at 18:21
  • You can define the available versions as distinct positive numerical values in a common header. Then your comparison approach should work. And you can check for unsupported values by comparing against , which also catches the case that `Name`? is undefined. – M Oehm Oct 07 '15 at 18:49
  • 2
    @PCLuddite -- not a duplicate at all; this sort of problem is much trickier if you're dealing with strings, but not too difficult in this case. – Charles Ofria Oct 07 '15 at 19:16
  • @PCLuddite I edited to clarify that none of the answers to that other question are useful here. How can I get rid of the *This question may already have an answer here:* tag? – Walter Oct 07 '15 at 22:12

2 Answers2

12

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.

Charles Ofria
  • 1,936
  • 12
  • 24
  • 2
    @sergej: Imagine if `Joe` and `Ben` are types: `NAME var = {3};`. Doesn't work if `#define NAME Joe` – Mooing Duck Oct 07 '15 at 20:31
  • 2
    @sergej: You're assuming that `Joe` and `Ben` are able to be defined as arbitrary numbers. If those symbols are instead meaningful, or are already macros, your simpler method doesn't work. Charles' method works regardless. – Mooing Duck Oct 07 '15 at 21:20
  • Would this still work with macro names defined via the compiler option `-DName=Joe`? – Walter Oct 07 '15 at 21:58
  • @undur_gongor You're absolutely right! I missed the change from `Name` to `NAME`. – Walter Oct 07 '15 at 22:17
-1

Pretty sure you'll find you can't in just c++ there are some ways with toolchain extensions people have found, but it's not portable. Another user asking something similar : Here

Community
  • 1
  • 1
BlindGarret
  • 155
  • 7
  • I didn't either, but the "toolchain extension" in the non-accepted answer to the linked question is a fantasy. See the third comment to that answer for an explanation. – rici Oct 07 '15 at 23:34