gcc (GCC) 4.7.2
c89
Run Code Online (Sandbox Code Playgroud)
是否可以对可变参数宏进行字符串化?
我有以下宏,我想从fmt和参数输出结果字符串.
#define ERROR_MESSAGE(priority, fmt, ...) \
do { \
MODULE_LOG(priority, fmt, ##__VA_ARGS__);\
} while(0)
Run Code Online (Sandbox Code Playgroud)
所以,我只是想获得的整个字符串fmt和##__VA_ARGS__这样我就可以把它分配给char *在其上执行一些额外的操作.
不.预处理在代码编译之前发生.它存在于与执行程序完全不同的世界中.您可以做的一件事就是只运行预处理步骤并检查输出(使用gcc开关-E打印预处理器输出).
您可以做的最多是将其重定向到一个文件,然后在程序中读取该文件.
进一步思考,让我从"不"退缩,并将其改为"也许".看一下我的另一个答案,它为可变参数宏实现了一个"foreach"宏.
因此,使用APPLYXn(和,隐式PPNARG),您可以将STR(x) #x宏应用于这样的args(写入的nb,APPLYXn最多可以处理15个参数):
#define X(x) #x
#define ERROR_MESSAGE(priority, fmt, ...) \
"do {MODULE_LOG(" X(priority) X(fmt) APPLYXn(__VA_ARGS__) ");} while(0)"
int main() {
printf("%s\n", ERROR_MESSAGE(3, "%d", 5) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc -E 产生
# 1 "strvar.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "strvar.c"
# 71 "strvar.c"
int main() {
printf("%s\n", "do {MODULE_LOG(" "3" "\"%d\"" "5" ");} while(0)" );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器会将所有这些字符串文字连接成一个字符串.