预处理器输出的差异

时间:2018-05-24 16:35:53

标签: c++ preprocessor

我试图检查一些具有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;中,但是在第一种情况下它们也是嵌套的,那么为什么预处理器没有错误呢?或者是否将责任委托给编译器?

编辑:我本不是要尝试实现任何功能,这只是一个练习(徒劳无功?)来理解预处理器。

1 个答案:

答案 0 :(得分:0)

仅在函数宏内部#具有特殊含义([cpp.stringize]p1)。该标准表示#需要后跟一个函数参数,这在第二种情况下不会发生(ifwarningendif不是参数)。

你的第一个案例是有效的(你实际上可以在对象宏的替换列表中有指令),因为#没有任何特殊含义。