停止宏扩展

Val*_*ouk 5 c c-preprocessor

我对宏扩展延迟有疑问。这是一个例子:

#include <stdio.h>

#define CONST_ABC 15
#define CONST_5 7
#define ABC 5

#define PRINT(x) printf("CONST=%d\n", CONST_ ## x)

// The problematic macro
#define PRINT2(x) PRINT(x)

int main(int argc, char *argv[])
{
    PRINT(ABC); // Prints 15 - OK
    PRINT2(ABC); // Prints 7 - Not OK.
}
Run Code Online (Sandbox Code Playgroud)

如何定义PRINT2宏以使其使用PRINT且结果为 15?我越来越:

CONST=15
CONST=7
Run Code Online (Sandbox Code Playgroud)

并想得到:

CONST=15
CONST=15
Run Code Online (Sandbox Code Playgroud)

Grz*_*ski 4

它要求您至少有一个 C99 编译器,因为 C99 允许空宏参数。然而,某些编译器可能允许它们作为扩展,即使在 C89 模式下也是如此。这是代码:

\n\n
#include <stdio.h>\n\n#define CONST_ABC 15\n#define CONST_5 7\n#define ABC 5\n\n#define PRINT(x) printf("CONST=%d\\n", CONST_ ## x)\n\n// The problematic macro\n#define PRINT2(x, y) PRINT(x ## y)\n\nint main(int argc, char *argv[])\n{\n    PRINT(ABC); // Prints 15 - OK\n    PRINT2(ABC,); // Prints 7 - Not OK.\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

第二个参数(即y)为空,使其成为空的预处理标记。该##运算符防止参数扩展,因此连接的结果与x

\n\n

C11 6.10.3.1/p1参数替换(强调我的):

\n\n
\n

在识别了调用类似函数的宏的参数后,将进行参数替换。替换列表中的参数,除非前面有###预处理标记或\n 后面有##预处理标记(见下文),否则在其中包含的所有宏都已展开后,将被相应的参数替换。在被替换之前,每个参数\xe2\x80\x99s 预处理标记都被完全宏替换,就好像它们形成\n 预处理文件的其余部分一样;没有其他可用的预处理标记。

\n
\n