C预处理器字符串化宏不计算算术表达式的解决方法咨询
问题根因
C标准规定预处理器的#字符串化操作仅会展开传入的宏参数,不会对参数内的算术表达式做求值,算术求值属于编译阶段的行为,在预处理器执行完成之后才会进行,因此你现有的写法只能拿到32/2的字面量字符串。
可行方案
方案1:静态断言快速查看值(C11及以上通用,无依赖)
故意写一个不成立的静态断言触发编译报错,编译器会直接输出表达式的计算结果:
#define BEGIN 32/2 _Static_assert(BEGIN == 0, "check BEGIN value");
编译报错信息会直接带出计算结果:
error: static assertion failed: "check BEGIN value"
note: the comparison reduces to '(16 == 0)'
方案2:预处理器分支实现结果字符串化(可直接用#pragma message输出)
利用预处理器在#if分支中支持算术求值的特性,把计算结果映射为字符串,适合数值范围固定的场景:
#define XSTR(x) STR(x) #define STR(x) #x #define BEGIN 32/2 /* 可根据你的数值范围扩展分支,也可以用宏循环简化分支代码 */ #if BEGIN == 16 # define BEGIN_STR "16" #elif BEGIN == 其他值 # define BEGIN_STR 对应字符串 #endif #pragma message ".text= " BEGIN_STR
编译后输出:#pragma message: .text= 16
方案3:GCC/Clang专属快速方案
如果使用GCC或Clang编译器,无需修改太多代码,仅需加一行常量定义,编译时加对应参数即可查看结果:
#define BEGIN 32/2 static const int __attribute__((unused)) BEGIN_VAL = BEGIN;
编译时添加-fdump-tree-original参数,生成的.original中间文件中会直接显示BEGIN_VAL的初始化值为16,无需解析lss文件。
内容的提问来源于stack exchange,提问作者Umbrecht
相关产品推荐
相关产品推荐

