为什么使用 clang 扩展宏时“##”没有消失?

Why the '##' not disappear when the macro expands by using clang?

我有这么简单的代码:

#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 提供更多参数?

按如下方式编辑您的宏:

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

然后:

void THE_MACRO(Hello)
{
}

正如@bmargulies 指出的那样,## 在宏上下文中可用。

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

所以,如果你想构建你的宏集,你可以这样做:

#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 成功调用。