“定义不明确的 for 循环 - 循环无限执行” (MSVC C6295)

Posted

技术标签:

【中文标题】“定义不明确的 for 循环 - 循环无限执行” (MSVC C6295)【英文标题】:"Ill-defined for-loop - loop executes infinitely" (MSVC C6295) 【发布时间】:2020-06-28 15:47:39 【问题描述】:

我不太确定为什么 Visual Studio 给我以下错误消息“定义错误的 for 循环:'unsigned int' 值始终在 '0' 到 '4294967295' 的范围内。循环无限执行”代码:

for (unsigned int i = list->GetCount() - 1; i >= 0; i--)

    // do stuff to each item (specifically in reverse order)

谁能给我解释一下?

编辑:GetCount() 返回一个无符号整数,我无法控制它

【问题讨论】:

作为unsigned 类型,i >= 0 总是正确的,根据定义。 unsigned 类型的变量不可能为负数。 哦!我忘记了这样一个事实,即当我到达 0 时,我会简单地“回绕”回来。那么,以负序遍历列表的最佳方法是什么?我的“get count”函数返回一个无符号整数 您可以将 getCount() 函数转换为 int,然后将 i 设置为 int。当 i 变为负数时,这将防止任何“环绕”。 unsigned 被高估了。 【参考方案1】:

当你从 unsigned 类型中减去 0 时,你得到的不是负数,而是一个非常大的正数。

这意味着这种情况:

i >= 0

将永远为真,导致无限循环。

您可以通过以下方式解决此问题:

for (int i = static_cast<int>(list->GetCount()) - 1; i >= 0; i--)

请注意,转换需要在之前减1,否则当GetCount返回0时,您将遇到相同的换行问题。

【讨论】:

这完全有道理,不敢相信我错过了。如果我的 GetCount() 函数返回一个无符号整数,我该如何浏览列表中的所有项目?将简单的 c 样式转换为 int 工作吗? 不,不要做 c 风格的演员表。一个 static_cast 就足够了。添加到答案中。 谢谢。在这种情况下,c 风格的演员阵容有什么问题? 如果GetCount() 返回的值大于有符号整数的最大值,则此解决方案将不起作用。您需要转换为更大的类型或使用不同的解决方案 this 的情况下没问题。但总的来说,这是不好的做法。 static_cast 更安全,应该在足够的时候使用。【参考方案2】:

您在这里犯了一个常见错误。当您将i 声明为unsigned int 时,您保证它永远不会是负数;相反,只要它低于0,它就会“环绕”到一个极高的数字。

这意味着你的 for 循环永远不会终止!您的终止条件i &gt;= 0永远得到满足,因为无符号整数将永远倒数 2、1、0、4294967295、4294967294... 等等。

要解决此问题,请将 unsigned int 类型更改为 int 类型。

【讨论】:

以上是关于“定义不明确的 for 循环 - 循环无限执行” (MSVC C6295)的主要内容,如果未能解决你的问题,请参考以下文章