【问题标题】:C stringification: convert constant to integer [closed]C字符串化:将常量转换为整数[关闭]
【发布时间】:2018-10-03 20:11:41
【问题描述】:

我需要将定义的常量转换为它们的整数值,所以我想出了这个宏 (STR_TO_CONST) 来这样做......

#define STRFY_VAL(s) #s
#define STRFY_KEY(s) STRFY_VAL(s)
#define STR_TO_CONST(s) atoi(STRFY_KEY(s))

它可以工作,但我想知道它是否存在任何潜在问题,因为我之前从未遇到过这个宏,尽管已经大量搜索过类似的东西。

【问题讨论】:

  • 我不确定我是否关注您的问题。你有你的用例的例子吗?

标签: c macros stringify stringification


【解决方案1】:

您从未遇到过这种情况的原因是它完全没有意义,但让我们通过示例来解释。假设您有以下内容:

#define FINALANSWER 42

// ...

int x = 2 * STR_TO_CONST(FINALANSWER);

现在,这在语义上与:

int x = 2 * FINALANSWER;

这是因为预处理器宏最终只是在您实际编译之前发生的文本替换。因此,FINALANSWER42 一样好。

您对一个不存在的问题的“解决方案”只是增加了开销,因为它向您的代码添加了一个新的字符串常量以及一个不必要的函数调用。

【讨论】:

  • 这使得它更难阅读和维护,因为你必须先弄清楚宏的作用。当然,这个名字很清楚,但情况并非总是如此。
  • 哦,它不必要地在运行时从 编译时常量 评估表达式......好吧,是的,只是不要这样做,我希望我的解释是足够好:)
  • 而且宏可能会产生意想不到的副作用...列表太长了。底线:除非绝对必须使用宏,否则请避免使用宏,即使那样,也要绝对确定自己知道自己在做什么。
  • 我会签署这个底线,至少对于初学者来说。我想补充一下宏很棒,如果你知道它们什么时候出现 ;)
  • 请注意,我没有就这是否是解决更广泛问题的适当解决方案征求意见。我只是询问代码是否存在任何明显的技术问题。
【解决方案2】:

我想知道它是否有任何潜在的问题(?)

是的。使用atoi() 初始化全局会导致类似“错误:初始化元素不是常量”

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2012-11-04
    • 2012-05-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 2014-03-15
    相关资源
    最近更新 更多