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.
const argv
? First time I see such a thing! The idea seems nice, but I'm not sure I like it: it makesmain
non-conformant and prevents me from doing something I never did ;) – Veracityargv
can be declared as something equivalent tochar* argv[]
(C99 5.1.2.2.1), and adding theconst
there doesn't change anything except whatmain()
is allowed to do with it (without a cast). Remember that a pointer to a non-const can be converted to a pointer to a const no problem - right down to the fact that values of those pointers will compare equal (6.3.2.3/2). – Stowellconst
) that would make it non-conformant. I'm beginning to like it! – Veracity