我需要将定义的常量转换为它们的整数值,所以我想出了这个宏(STR_TO_CONST)...
#define STRFY_VAL(s) #s
#define STRFY_KEY(s) STRFY_VAL(s)
#define STR_TO_CONST(s) atoi(STRFY_KEY(s))
它有效,但我想知道它是否有任何潜在的问题,因为我之前从未遇到过这个宏,尽管我已经大量搜索了类似的东西。
答案 0 :(得分:5)
你从未遇到过这个问题的原因是它毫无意义,但让我们通过例子来解释。假设您有以下内容:
#define FINALANSWER 42
// ...
int x = 2 * STR_TO_CONST(FINALANSWER);
现在,这在语义上没有区别:
int x = 2 * FINALANSWER;
这是因为预处理器宏最终只是在您实际编译之前发生的文本替换。因此,FINALANSWER
与整数常量一样好42
。
您的解决方案"对于一个不存在的问题只会增加开销,因为它会为你的代码添加一个新的字符串常量以及一个不必要的函数调用。
答案 1 :(得分:1)
我想知道它是否有任何潜在的问题(?)
是。使用atoi()
初始化全局结果,例如“error:initializer element is not constant”
int x = STR_TO_CONST(123); // error
int y = 123; // no error
int main(void) {
return x + y;
}
隐藏警告。只有1行产生了有用的警告 “警告:隐式常量转换溢出[-Woverflow]”
int main(void) {
int a = STR_TO_CONST(123456789012345); // no warning
int b = 123456789012345; // warning
return a + b;
}
范围问题。对于32位int
,以下内容可能会超出atoi()
范围,从而导致未定义的行为而没有任何警告。
int main(void) {
long long z = STR_TO_CONST(123456789012345);
return !z;
}