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 |