我试图检查一些具有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;
}
为什么会出现此错误?当然,这不会编译,但我想知道为什么在预处理器的解析错误中会出现添加参数的原因?
人们会说&#34;你不能将另一个指令嵌套在另一个&#34;中,但是在第一种情况下它们也是嵌套的,那么为什么预处理器没有错误呢?或者是否将责任委托给编译器?
编辑:我本不是要尝试实现任何功能,这只是一个练习(徒劳无功?)来理解预处理器。
答案 0 :(得分:0)
仅在函数宏内部#
具有特殊含义([cpp.stringize]p1)。该标准表示#
需要后跟一个函数参数,这在第二种情况下不会发生(if
,warning
和endif
不是参数)。
你的第一个案例是有效的(你实际上可以在对象宏的替换列表中有指令),因为#
没有任何特殊含义。