C 预处理器 : Evaluate macro early

标签 c macros c-preprocessor

考虑以下设置:

啊.h

#define A 5
#define B A
#undef A
#define A 3

交流

#include "a.h"
#include <stdio.h>

int main()
{
    printf("%d\n", B);
    return 0;
}

虽然这非常合理地打印 3,但有没有办法让它打印 5,即在 a.h 的第二行用 5 替换 A?

最佳答案

不,没有办法做到这一点。除非您知道 A 的所有可能值,并且它们总是整数,在这种情况下您可以费力地依次测试每个值:

#if A == 0
# define B 0
#elif A == 1
# define B 1
#elif A == 2
# define B 2
/*  ... and a very long etc. */
#endif

如果您的用例仅涉及整数,则您有更多选择。例如,您可以将 B 声明为 static const intenum(取决于语言)而不是宏,这显然会使用宏的当前值。如果你真的想要宏,Boost 预处理库有一个 implementation上面费力的 #if 序列(巧妙地减少了 log(N) 而不是 N 所需的预处理器语句的数量)。


#define预处理器指令中没有宏替换; §6.10 段涵盖了这一事实。 C 标准的第 7 条(C++ 标准的第 16 段第 6 段,措辞相同):

The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.

#if#include 指令的描述中,标准规定确实会发生宏替换,这就是为什么#if 上面的解决方案有效(和 Boost 实现,它也使用计算的 #include)。

关于C 预处理器 : Evaluate macro early,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34486726/

相关文章:

c - 在c中使用基于区域的内存管理

c - 为什么程序卡在 child 与 parent 的沟通上?

c - 当宏间接扩展自身时,了解 C 的预处理器的行为

macros - 在编写可加载内核模块时需要使用 module_init 和 module_exit 等宏

C 将方程结果字符串化

C- 检查第一个命令行参数中的第一个字符是否包含特定字符

c - 应用程序未收到 iptable 修改的 Netlink 通知

compiler-construction - 方案中的匿名宏

编译错误 - 已弃用的扩展

c - libc6 : comma operator in assert macro definition