【问题标题】:Constant value in conditional expression条件表达式中的常量值
【发布时间】:2010-09-18 11:22:35
【问题描述】:

coding style question about infinite loops 中,一些人提到他们更喜欢 for(;;) 样式,因为 while(true) 样式会在 MSVC 上发出有关条件表达式为常量的警告消息。

这让我大吃一惊,因为在条件表达式中使用常量值是避免 #ifdef 地狱的有用方法。例如,您可以在标题中包含:

#ifdef CONFIG_FOO
extern int foo_enabled;
#else
#define foo_enabled 0
#endif

并且代码可以简单地使用条件并信任编译器在未定义 CONFIG_FOO 时删除死代码:

if (foo_enabled) {
    ...
}

不必每次使用 foo_enabled 时都测试 CONFIG_FOO:

#ifdef CONFIG_FOO
if (foo_enabled) {
    ...
}
#endif

这种设计模式一直在 Linux 内核中使用(例如,include/linux/cpumask.h 定义了几个宏,当 SMP 禁用时为 1 或 0,当 SMP 启用时定义为函数调用)。

该 MSVC 警告的原因是什么?此外,有没有更好的方法来避免 #ifdef 地狱而不必禁用该警告?还是一般不应启用的过于宽泛的警告?

【问题讨论】:

    标签: c++ c warnings visual-c++


    【解决方案1】:

    警告并不意味着代码不好,只是看起来很可疑。

    就我个人而言,我从启用所有可能的警告开始,然后关闭任何被证明比有用更烦人的警告。每当您将任何内容转换为布尔值时都会触发的那个通常是第一个触发的。

    【讨论】:

      【解决方案2】:

      我认为警告的原因是您可能无意中有一个更复杂的表达式,它在没有意识到的情况下计算为一个常量。假设您在标题中有这样的声明:

      const int x = 0;
      

      然后,远离 x 的声明,您有如下条件:

      if (x != 0) ...
      

      您可能没有注意到它是一个常量表达式。

      【讨论】:

        【解决方案3】:

        我相信这是为了捕捉像

        这样的东西
         if( x=0 )
        

        当你的意思是

         if( x==0 )
        

        【讨论】:

        • 好点。这是人们看到像“if (0 == x)”这样的“向后”比较的原因之一——如果你错过了一个 = 符号,编译器就会捕捉到它!
        • 如果这是它想要捕捉的,难道它不能只捕捉那个(条件内的赋值)而不是更一般的警告吗?
        • 这会产生不同的警告。使用 VC++ 是:编译器警告(级别 4)条件表达式中的 C4706 赋值
        【解决方案4】:

        避免警告的简单方法是:

        #ifdef CONFIG_FOO
        extern int foo_enabled;
        #else
        extern int foo_enabled = 0;
        #endif
        

        【讨论】:

        • 你确定你可以extern一个变量同时给它一个值吗?如果它被初始化为定义它的不同值怎么办? “静态常量 int foo_enabled = 0;”会是更好的选择。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-31
        • 1970-01-01
        • 2015-08-09
        • 1970-01-01
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多