3

I have

#define A_T 1
#define B_T 2
int x_a = 1, x_b =2;

How can I define a macro, which can concatenate the suffix _a and _b to the var name?

for example, something like this
#define A_T_SUF _a
#define B_t_SUF _b
#define SUFFIX(t) t ## _SUF 
#define VAR_SUF(var, t) var ## SUFFIX(t) 
.....
VAR_SUF(x, A_T) ---> be replaced to x_a

Is this possible?

Cœur
  • 37,241
  • 25
  • 195
  • 267
wei
  • 6,629
  • 7
  • 40
  • 52
  • 1
    possible duplicate of [C preprocessor and concatenation](http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation) – Jonathan Leffler May 13 '13 at 23:17

1 Answers1

6

You need an extra indirection in the VAR_SUF macro to force it to evaluate the called macros before concatenating the tokens instead of concatenating first:

#define A_T_SUF _a
#define B_t_SUF _b
#define SUFFIX(t) t ## _SUF 
#define CAT(a, b) a ## b
#define XCAT(a, b) CAT(a, b)
#define VAR_SUF(var, t) XCAT(var, SUFFIX(t)) 
.....
VAR_SUF(x, A_T) ---> be replaced to x_a

without the extra indirect, VAR_SUF(x, A_T) would expand to xSUFFIX(A_T) (concatenate first, then look for more macros). With the extra CAT/XCAT indirection, it will expand SUFFIX(A_T) first and then concatenate.

XCAT is short for EXPAND_AND_CONCATENATE, while CAT is just CONCATENATE (without expansion.)

edit

If A_T is also a macro (eg, #define A_T 1) then it will be replaced first. You can avoid that by removing the indirection of the ## in the SUFFIX macro:

#define A_T_SUF _a
#define B_t_SUF _b
#define CAT(a, b) a ## b
#define XCAT(a, b) CAT(a, b)
#define VAR_SUF(var, t) XCAT(var, t##_SUF) 
.....
VAR_SUF(x, A_T) ---> be replaced to x_a

This will cause that concatenation to happen first, then macros will be expanded, then the other concatenation will happen

If x is also a macro, then you have a problem, as there's no good way to expand one token and not the other before you concatenate them.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • This does not seem to work. looks like A_T is always replaced with 1 first. – wei May 13 '13 at 23:56
  • Yes, if `A_T` is also defined as a macro, then it will get replaced first. Avoiding that requires doing SUFFIX directly rather than as a macro – Chris Dodd May 14 '13 at 14:02