0

I'm trying to use multiple macros in the definition of another macro, but seem to have problems concatenating them together. Here's a very simplified version of what I'm trying to do:

#include <stdio.h>

#define PICK_SET_A

#ifdef PICK_SET_A
#define SET A
#endif
#ifdef PICK_SET_B
#define SET B
#endif

#define ENABLE_VAR_1_A   1
#define ENABLE_VAR_2_A   1

#define ENABLE_VAR_1_B   0
#define ENABLE_VAR_2_B   0

#define MACRO_RESOLVE(var,set) ENABLE_VAR_##var##_##set

#define ENABLE_VAR_1     MACRO_RESOLVE(1, SET)
#define ENABLE_VAR_2     MACRO_RESOLVE(2, SET)

int main(int argc, char **argv) {

    fprintf(stdout, "VALUE: %d\n", ENABLE_VAR_1);

    return 0;
}

I would expect the result to be 0.

However, I'm getting compile errors because the MACRO_RESOLVE macro isn't resolving the way I expect it to:

$ gcc -o asdf asdf.c
asdf.c:25:36: error: use of undeclared identifier 'ENABLE_VAR_1_SET'
    fprintf(stdout, "VALUE: %d\n", ENABLE_VAR_1);
                                   ^
asdf.c:20:26: note: expanded from macro 'ENABLE_VAR_1'
#define ENABLE_VAR_1     MACRO_RESOLVE(1, SET)
                         ^
asdf.c:18:32: note: expanded from macro 'MACRO_RESOLVE'
#define MACRO_RESOLVE(var,set) ENABLE_VAR_##var##_##set
                               ^
<scratch space>:229:1: note: expanded from here
ENABLE_VAR_1_SET
^
1 error generated.

So it looks like SET isn't getting expanded when I define ENABLE_VAR_1.

Wesley Bland
  • 8,816
  • 3
  • 44
  • 59
  • I'd be fine with other solutions to this problem. The main goal is to be able to have two macros inserted into the definition of another macro like this. – Wesley Bland Nov 06 '16 at 16:06
  • Why are you trying to do this with macros? – Ed Heal Nov 06 '16 at 16:07
  • Related: [*Why is a level of indirection needed for this concatenation macro?*](http://stackoverflow.com/questions/19666142) – DaoWen Nov 06 '16 at 17:55
  • @EdHeal By doing this in macros, I can avoid function calls and memory lookups whenever possible. I'll be happy to point to my GitHub PR when I'm done with it, but the short version is that sometimes I want this to be resolved at compile time (with all these macros) and sometimes it has to be resolved at runtime. – Wesley Bland Nov 06 '16 at 19:48

1 Answers1

1

Since you are trying to build a macro name, you need to do enough intermediate expansions along the way for all tokens to expand. See it live here.

#include <stdio.h>

#define PICK_SET_A

#ifdef PICK_SET_A
#define SET A
#endif
#ifdef PICK_SET_B
#define SET B
#endif

#define ENABLE_VAR_1_A   1
#define ENABLE_VAR_2_A   1

#define ENABLE_VAR_1_B   0
#define ENABLE_VAR_2_B   0

#define MACRO_RESOLVE__(M) M
#define MACRO_RESOLVE_(V, S) MACRO_RESOLVE__(ENABLE_VAR_ ## V ##_## S)
#define MACRO_RESOLVE(var,set) MACRO_RESOLVE_(var, set)

#define ENABLE_VAR_1     MACRO_RESOLVE(1, SET)
#define ENABLE_VAR_2     MACRO_RESOLVE(2, SET)

int main(int argc, char **argv) {

    fprintf(stdout, "VALUE: %d\n", ENABLE_VAR_1);

    return 0;
}
Wesley Bland
  • 8,816
  • 3
  • 44
  • 59
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458