为“while(true)”发出编译器警告而不为“for(;;)”发出编译器警告有什么意义?

问题描述 投票:0回答:5

当我使用 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
}

编译时没有警告。

为什么会出现这种差异,尤其是第二个和第三个变体之间?

c++ visual-c++ compiler-warnings
5个回答
10
投票

警告用户常量条件表达式的原因是为了帮助避免表达式最终成为常量的错误(例如,由于拼写错误)。在最后一种情况下,没有表达式,因此不存在意外变为常量的风险。


7
投票

原因很简单,虽然很愚蠢。

诊断无限循环很重要,但这可能并不明显:

while(i >= 0) { --i; } // infinite if i unsigned

while(SOME_MACRO(i)) // err, depends on the expansion of macros

编译器的一个重要功能是为同义反复测试生成警告,该测试结果要么总是为真,要么总是为假,因为当它来自宏扩展或在依赖上下文中时,它并不明显.

VC++ 在这里似乎有点太过分了,它没有考虑同义反复条件,而是对它能找到的所有

true
false
条件发出警告,即使它们已经在代码中明确说明了。


4
投票

for ( ;; )
构造是有意编码“无限”循环的规范方法。我可以想象编译器设计者不想为此生成警告。


4
投票

没有意义。毕竟,语言规范说($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) { // ... }

1
投票
在这种情况下,在优化构建中,编译器可能会推断出条件始终为真(因为无符号整数不能小于 0)。因此需要在

true

 循环中检测始终 
while
 条件。我认为编写此类错误检测的人并没有对 
while (true)

进行特殊处理,因为有一种简单的方法可以使用
for (;;)
进行无限循环。

您可以阅读
here
,如何决定在 Visual Studio 中添加或不添加警告(示例是关于 
C#
,但我认为团队对于 
C++
 中的警告有相同的经验法则) .

© www.soinside.com 2019 - 2024. All rights reserved.