为什么' ##'当宏使用clang扩展时不会消失?

时间:2015-06-25 02:08:30

标签: c++ clang c-preprocessor

我有这么简单的代码:

#define THE_MACRO World

void Hello##THE_MACRO()
{
}

通过clang++ code.cpp -E预处理,我得到了这样的结果:

# 1 "code.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 326 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "code.cpp" 2


void Hello##World()
{
}

请注意##仍然保留在代码中并导致编译错误:

code.cpp:3:6: error: variable has incomplete type 'void'
void Hello##THE_MACRO()
     ^
code.cpp:3:11: error: expected ';' after top level declarator
void Hello##THE_MACRO()
          ^
          ;

我无法弄清楚代码有什么问题。应该为clang提供更多的参数吗?

2 个答案:

答案 0 :(得分:1)

按如下方式编辑宏:

#define THE_MACRO(x) x ## World()

然后:

void THE_MACRO(Hello)
{
}

正如@bmargulies指出的那样,##在宏观背景下可用。

答案 1 :(得分:1)

##运算符必须出现在宏内部。宏按它们可用的顺序处理,但如果一个宏的结果产生一个新的宏,那么它也将被处理。因此,有时您希望有一个宏调用另一个实际实现该功能的宏(并在稍后定义),以确保正确处理参数。

因此,如果您想构建一组宏,可以这样做:

#include <iostream>

#define MERGE(A,B) MERGE_IMPL(A,B)
#define MERGE_IMPL(A,B) A ## B

#define XXX Hello
#define YYY World

void MERGE(XXX, YYY)() {
  std::cout << "Yay!" << std::endl;
}

int main() {
  HelloWorld();
}

上面的程序应该运行,正确翻译宏,允许定义HelloWorld()函数并从main成功调用。