C编程:预处理器,宏作为标记

我正在尝试做一些概念上与此相似的事情,但似乎无法让它发挥作用(最后显示的错误)任何想法?

#include  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) 

你只需要额外的间接:

 #include  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; } 

即使它看起来多余,但事实并非如此。

正确使用字符串化( # )或标记粘贴( ## )预处理运算符的通常习惯是使用第二级间接。 ( ##预处理器运算符的应用程序和陷阱需要考虑哪些? )。

 #define STRINGIFY2( x) #x #define STRINGIFY(x) STRINGIFY2(x) #define PASTE2( a, b) a##b #define PASTE( a, b) PASTE2( a, b) 

然后:

 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; } 

应该给你你想要的结果。

基本上,会发生的是###运算符的处理在宏替换之前发生。 然后发生另一轮宏观替换。 因此,如果您希望将宏与这些操作一起使用,则必须使用仅执行替换的第1级 – 否则首先进行字符串化或粘贴,并且宏不再是宏 – 它们都是第1轮的字符串化/粘贴产生。

更直接地说 – 第一级宏允许替换宏参数,然后第二级宏替换执行stringify / token-pasting操作。

这适用于足够的间接级别。 虽然另一个答案是足够的,但我想提供这段代码作为演示:

 #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) 

保存这是一个文本文件xc,只对它进行预处理。

 gcc -E xc 

观察和思考。 我完全不了解它。 花两个小时尝试使用stringify来运行宏。 有趣的是,有时需要双重间接。