C++ 条件表达式中的常量值

C++ 条件表达式中的常量值,c++,c,warnings,visual-c++,C++,C,Warnings,Visual C++,在一个例子中,一些人提到他们更喜欢for(;;)样式,因为while(true)样式在MSVC上给出了关于条件表达式为常量的警告消息 这让我大吃一惊,因为在条件表达式中使用常量值是避免“ifdef地狱”的有效方法。例如,标题中可以有: #ifdef CONFIG_FOO extern int foo_enabled; #else #define foo_enabled 0 #endif 代码可以简单地使用一个条件,并在未定义CONFIG_FOO时信任编译器删除死代码: if (foo_enab

在一个例子中,一些人提到他们更喜欢for(;;)样式,因为while(true)样式在MSVC上给出了关于条件表达式为常量的警告消息

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

#ifdef CONFIG_FOO
extern int foo_enabled;
#else
#define foo_enabled 0
#endif
代码可以简单地使用一个条件,并在未定义CONFIG_FOO时信任编译器删除死代码:

if (foo_enabled) {
    ...
}
与每次使用FOO\u enabled时都必须测试CONFIG\u FOO不同:

#ifdef CONFIG_FOO
if (foo_enabled) {
    ...
}
#endif
此设计模式在Linux内核中一直使用(例如,include/Linux/cpumask.h在禁用SMP时将多个宏定义为1或0,在启用SMP时将多个宏定义为函数调用)


MSVC发出警告的原因是什么?此外,有没有更好的方法避免“ifdef地狱”,而不必禁用该警告?或者这是一个过于宽泛的警告,一般不应该启用它?

我相信它是为了捕捉类似的东西

 if( x=0 )
你什么意思

 if( x==0 )

避免警告的简单方法是:

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

我认为发出警告的原因是,您可能无意中得到了一个更复杂的表达式,该表达式的计算结果为常数,但却没有意识到这一点。假设在标题中有这样的声明:

const int x = 0;
之后,与x的声明不同,您有一个条件,如:

if (x != 0) ...

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

警告并不自动意味着代码不好,只是看起来可疑而已


就我个人而言,我从一个能够启用所有警告的位置开始,然后关闭任何被证明是恼人而不是有用的警告。只要你把任何东西扔到桶里,就会开火的那一个通常是第一个发射的。

说得好。这就是人们看到“向后”比较的一个原因,比如“if(0==x)”--如果您缺少一个=符号,编译器将捕获它!如果这就是它想要捕捉的,它不能只捕捉那个(条件中的赋值)而不是更一般的警告吗?这会生成不同的警告。使用VC++时,它是:编译器警告(级别4)C4706条件表达式中的赋值。您确定可以外部化一个变量,同时给它一个值吗?如果它被初始化为定义它的另一个值呢?“static const int foo_enabled=0;”将是更好的选择。