21

我发现了一篇有趣的小博客文章,它解释了如何使用行号在宏中生成(半)唯一名称:

// Do magic! Creates a unique name using the line number
#define LINE_NAME( prefix ) JOIN( prefix, __LINE__ )
#define JOIN( symbol1, symbol2 ) _DO_JOIN( symbol1, symbol2 )
#define _DO_JOIN( symbol1, symbol2 ) symbol1##symbol2

这里有两件事让我很困惑:

  1. 为什么LINE_NAME宏即使JOIN在文件中声明后也能工作?我认为 C 预处理器进行了线性传递,因此需要根据依赖关系定义宏,就像在使用 C 函数之前需要定义它们一样。
  2. 为什么必须同时使用JOIN_DO_JOIN宏才能获得正确的结果?在宏中具有这种间接级别似乎很奇怪。

我觉得这两个问题的答案是相关的,并且与 C 预处理器评估宏的方式有关。(然而,我对宏如何工作的直觉显然是错误的,因为我什至不认为这个例子是有效的。)

4

1 回答 1

13

为什么 LINE_NAME 宏即使在文件中声明 JOIN 之后也能工作?

宏不是函数,当您调用它们时,编译器会扩展它们,并且使用点的编译器知道所有已定义的宏。

为什么必须同时使用 JOIN 和 _DO_JOIN 宏才能获得正确的结果?在宏中具有这种间接级别似乎很奇怪。

因为__LINE__它本身就是一个宏,所以需要两级扩展。

否则输出不是prefix1234它会的prefix__LINE__

阅读这个答案这个线程也很有用。

于 2013-10-29T18:21:50.903 回答