关于c ++:条件表达式中的常数

Constant value in conditional expression

在有关无限循环的编码样式问题中,有人提到他们更喜欢for(;;)样式,因为while(true)样式会在MSVC上发出有关条件表达式恒定的警告消息。

这使我非常惊讶,因为在条件表达式中使用常量值是避免#ifdef地狱的有用方法。例如,您可以在标题中输入:

1
2
3
4
5
#ifdef CONFIG_FOO
extern int foo_enabled;
#else
#define foo_enabled 0
#endif

当未定义CONFIG_FOO时,代码可以简单地使用条件代码并信任编译器来清除无效代码:

1
2
3
if (foo_enabled) {
    ...
}

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

1
2
3
4
5
#ifdef CONFIG_FOO
if (foo_enabled) {
    ...
}
#endif

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

该MSVC警告的原因是什么?另外,有没有更好的方法可以避免#ifdef地狱而不必禁用该警告?还是一般不应启用的范围太广的警告?


警告并不自动表示代码是错误的,只是看起来可疑。

就我个人而言,我从启用所有可能的警告的位置开始,然后关闭所有烦人的有用警告。 每当您将任何东西投向布尔时都会触发的那个通常是第一个出现的。


我认为发出警告的原因是,您可能无意中使用了一个更复杂的表达式,该表达式在没有意识到的情况下对常量的求值。 假设您在标头中有一个这样的声明:

1
const int x = 0;

然后,在远离x的声明的地方,您有一个类似以下的条件:

1
if (x != 0) ...

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


我相信这是赶上

1
 if( x=0 )

当你的意思

1
 if( x==0 )


避免警告的简单方法是:

1
2
3
4
5
#ifdef CONFIG_FOO
extern int foo_enabled;
#else
extern int foo_enabled = 0;
#endif