问题
I'm trying to do something that is conceptually similar to this, but can't seem to get it to work (error shown at end) any ideas?
#include <stdio.h>
int main( int argc , char const *argv[] )
{
int abc_def_ghi = 42;
#define SUFFIX ghi
#define VAR(prefix) prefix##_def_##SUFFIX
printf( "%d\n" , VAR(abc) );
return 0;
}
// untitled:8: error: ‘abc_def_SUFFIX’ undeclared (first use in this function)
回答1:
You just need additional indirection:
#include <stdio.h>
int main( int argc , char const *argv[] )
{
int abc_def_ghi = 42;
#define SUFFIX ghi
#define VAR3(prefix, suffix) prefix##_def_##suffix
#define VAR2(prefix, suffix) VAR3(prefix, suffix)
#define VAR(prefix) VAR2(prefix, SUFFIX)
printf( "%d\n" , VAR(abc) );
return 0;
}
Even though it looks redundant, it's not.
回答2:
The usual idiom for correctly using the stringizing (#
) or token pasting (##
) pre-processing operators is to use a 2nd level of indirection. (What are the applications of the ## preprocessor operator and gotchas to consider?).
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
Then:
int main( int argc , char const *argv[] )
{
int abc_def_ghi = 42;
#define SUFFIX ghi
#define VAR(prefix) PASTE( prefix, PASTE( _def_, SUFFIX))
printf( "%d\n" , VAR(abc) );
return 0;
}
Should give you the results you're looking for.
Basically, what happens is that processing of the #
and ##
operators takes place before macro replacement. Then another round of macro replacement occurs. So if you want macros to be used along with those operations you have to use a 1st level that simply does the replacement - otherwise the stringizing or pasting happens first, and the macros aren't macros anymore- they're whatever the 1st round of stringizing/pasting produces.
To put it more directly - the first level of macro allows the macro parameters to be replaced, then the 2nd level of macro replacement does the stringify/token-pasting operation.
回答3:
This works with sufficient levels of indirection. While another answer is plenty adequate, I want offer this chunk of code as a demo:
#define SUFFIX ghi
#define VAR1(prefix) prefix##_def_##SUFFIX
VAR1(abc)
#define VAR2_(prefix, sfx) prefix##_def_##sfx
#define VAR2(prefix) VAR2_(prefix,SUFFIX)
VAR2(abc)
#define VAR3_(prefix, sfx) prefix##_def_##sfx
#define VAR3x(prefix,sfx) VAR3_(prefix,sfx)
#define VAR3(prefix) VAR3x(prefix,SUFFIX)
VAR3(abc)
Save this is a text file, x.c, and only preprocess it.
gcc -E x.c
Observe and ponder. I don't quite understand it entirely myself. Just spend two hours trying to get a macro using stringify to work. It is interesting to see that double indirection is sometimes needed.
来源:https://stackoverflow.com/questions/1767683/c-programming-preprocessor-macros-as-tokens