2

I have an list of tokens defined as:

#define TOKENS ACC, STOP, RUN, BACK

This list might change. I would like to create an array of function pointers based on that list by doing something similar to:

int (*callbacks[])(const char * arg) =
{
   some_macro_shenanigans(TOKENS)
};

And some_macro_shenanigans(TOKENS) should expand to ACC_callback, STOP_callback, ... and so on. Later I would like to create an array of strings based on TOKENS like this:

const char * const token_str[] = some_other_macro_shenanigans(TOKENS);

Which would expand to something equivalent to this:

const char * const token_str[] = [ "ACC", "STOP", "RUN", "BACK" /* and others if present */ ];

Is it doable?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Qpieloq
  • 33
  • 7
  • 5
    I think you need to look up "x-macros". See, for example, [Real-world use of X-macros?](https://stackoverflow.com/q/6635851/15168). There's even a tag for questions about them: [tag:x-macros]. – Jonathan Leffler Aug 23 '22 at 14:35

1 Answers1

3

Sure, using x-macros (as comments point towards):

#define TOKENS(DO) \
    DO(ACC) \
    DO(STOP) \
    DO(RUN) \
    DO(BACK) 

#define GEN_CALLBACK(ID) ID##_callback,
#define GEN_NAME(ID) #ID,

int (*callbacks[])(const char * arg) = { TOKENS(GEN_CALLBACK) };
const char * const token_str[] = [ TOKENS(GEN_NAME) ];

preprocesses to (godbolt link)

int (*callbacks[])(const char * arg) = { ACC_callback, STOP_callback, RUN_callback, BACK_callback, };
const char * const token_str[] = [ "ACC", "STOP", "RUN", "BACK", ];
AKX
  • 152,115
  • 15
  • 115
  • 172