当我使用 Visual C++ 9 编译 C++ 代码时,“警告级别 4”如下:
while( true ) {
//loop body with break on certain condition
}
以及以下内容:
for( ; true; ) {
//same loop body
}
两者都会触发
C4127: conditional expression is constant
警告,但以下内容:
for( ; ; ) {
//same loop body
}
编译时没有警告。
为什么会出现这种差异,尤其是第二个和第三个变体之间?
警告用户常量条件表达式的原因是为了帮助避免表达式最终成为常量的错误(例如,由于拼写错误)。在最后一种情况下,没有表达式,因此不存在意外变为常量的风险。
原因很简单,虽然很愚蠢。
诊断无限循环很重要,但这可能并不明显:
while(i >= 0) { --i; } // infinite if i unsigned
while(SOME_MACRO(i)) // err, depends on the expansion of macros
编译器的一个重要功能是为同义反复测试生成警告,该测试结果要么总是为真,要么总是为假,因为当它来自宏扩展或在依赖上下文中时,它并不明显.
VC++ 在这里似乎有点太过分了,它没有考虑同义反复条件,而是对它能找到的所有
true
或 false
条件发出警告,即使它们已经在代码中明确说明了。
for ( ;; )
构造是有意编码“无限”循环的规范方法。我可以想象编译器设计者不想为此生成警告。
没有意义。毕竟,语言规范说($6.5.3/2),
条件和中的一个或两个 表达式可以省略。 A 缺失条件使得隐含的 while 子句相当于 而(真)。
因此,即使根据标准,
for ( ; ; )
也等同于 while(true)
。因此,我不认为编译器应该在一种情况下发出警告,而在另一种情况下则不发出警告!
--
如果编译器决定发出警告,那么在我看来,编译器应该在条件“缺失”时发出警告,而不是在条件存在时发出警告,这样警告将被解释为“提示”,以便程序员提及他的“意图清楚且明确。
我的意思是,for ( ;; )
比for ( ;true; )
Steve
在评论中所说:对于 int 值 y,char x = y 是 相当于 char x = (char)y,但是 你可能想要一个警告 隐式缩小转换 第一个,但不是第二个。 所以显式意图不应该收到警告,而隐式意图应该收到警告!
循环中使用始终编译器警告可帮助捕获潜在的错误。在
true
while
条件可能是一个错误。例如,在下面的代码中,这可能是一个错误,我希望编译器警告我:
unsigned int x;
// ...
while (x >= 0) {
// ...
}