c - 为什么这个串联宏需要一个间接级别?

标签 c macros concat

我找到了 an interesting little blog post这解释了如何使用行号在宏中生成(半)唯一名称:

// 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 预处理器评估宏的方式有关。 (但是,我对宏如何工作的直觉显然有偏差,因为我什至不认为这个例子是有效的。)

最佳答案

Why does the LINE_NAME macro even work if JOIN is declared after it in the file?

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

Why is it necessary to use both the JOIN and _DO_JOIN macros in order to get the correct result? Having this level of indirection in the macros seems very strange.

由于__LINE__本身就是一个宏,需要二级展开。

否则输出不是prefix1234,而是prefix__LINE__

阅读 this answer 很有用还有,this thread .

关于c - 为什么这个串联宏需要一个间接级别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19666142/

相关文章:

c - 如何维护字符串与其在 C 中的索引之间的映射?

c - "SIGSEGV on thread"错误

c++ - 宏的问题

python - gdb API 预处理器宏

c - #define 使用结构化指针中的成员

arrays - 如何在mongodb中连接数字和字符串值?

sql - 使用 SUBSTR Oracle SQL 将 SPACE 添加到 CONCAT

MYSQL 连接最大长度

java - 如何使用 JNI 在 C 中获取原始 Android 相机缓冲区?

c++ - 在运行时检测和拦截链接库依赖项