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来运行宏。 有趣的是,有时需要双重间接。