【发布时间】:2018-05-24 16:35:52
【问题描述】:
我试图检查一些具有 2 个预处理器指令的单行宏。
#define REPLACE { \
#if EXT == 42 \
#warning "Got 42" \
#endif \
}
int main(void){
REPLACE;
return 0;
}
预处理器解析这个精细的产量:
$g++ -E includetest.cpp
# 1 "includetest.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "includetest.cpp"
int main(void){
{ #if EXT == 42 #warning "Got 42" #endif };
return 0;
}
这当然是非法代码,因为只是发生了宏替换,并且 ifdef 相似宏即使看起来像一个宏也不会再次处理。
现在,如果我稍微改变宏看起来像
#define REPLACE(a) { a + 2 ; \
#if EXT == 42 \
#warning "Got 42" \
#endif \
}
int main(void){
REPLACE(0);
return 0;
}
这会产生此预处理器错误:
$g++ -E includetest.cpp
# 1 "includetest.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "includetest.cpp"
includetest.cpp:1:18: error: '#' is not followed by a macro parameter
#define REPLACE(a) { a + 2 ; \
^
int main(void){
REPLACE(0);
return 0;
}
为什么会出现这个错误?当然,这不会编译,但我想知道为什么添加参数会导致预处理器的解析错误?
人们会说“你不能在另一个指令中嵌套另一个指令”,但在第一种情况下它们也是嵌套的,为什么预处理器不会出错呢?还是该责任委托给编译器?
编辑:我本身并不想实现任何功能,这只是一个练习(徒劳?)以了解预处理器。
【问题讨论】:
-
您期望预处理器提供一些它根本无法做到的事情。它不会递归替换,它只有一次。顺便说一句,你想做的 99% 都可以用纯 c++ 实现,c++ 永远不需要复杂的宏
-
因为一个宏不能用来定义另一个宏,你为什么要关心?
-
@pm100 我想你还没有理解我的问题。我在问为什么输出有差异。我不希望它“做事”,我只是在问它为什么会这样?
-
@NeilButterworth 好的。您能否指导我参考其中提到的标准或参考?我找不到它。这也不是另一个“宏中的宏”,对吧?这只是同一行中的另一个指令。
-
第一个是类对象宏,第二个是类函数宏。宏函数会作用于宏函数参数,这是
#if试图做的,但是if不是宏参数,所以失败了。
标签: c++ preprocessor