5

我很难理解为什么以下代码没有警告:

unsigned test = 0xffffffff;

for (unsigned char i = 0; i < test; i++)
{
    // Some code
}

这是在 Visual Studio 2010 上,但 GCC 显然也没有警告。有谁知道为什么?

4

4 回答 4

6

从语言的角度来看,没有什么可警告的。 在评估之前i被提升到。并且它是完全明确定义的,它增加一个这样它环绕到零。unsigned int<unsigned char

不幸的是,这段代码做了一些令人讨厌的事情。但目前尚不清楚编译器需要应用什么规则才能检测到这类事情。

感谢下面评论中的@unwind:您可以让 GCC 警告这样一个事实,即该比较必须始终使用-Wtype-limits标志评估为真。

更新 2:显然上述选项在这种情况下不起作用(我现在手头没有“现代”版本的 GCC ......)

于 2013-03-21T10:50:54.190 回答
1

i被提升到unsigned,然后与 比较test。这里没有问题。出色地。i++ 会溢出字符,但这是一个运行时问题。我的意思是,在 255 之后它将为 0,这可能不是作者所期望的,如果没有其他形式的终止它(中断、重新调整等),则使循环可能无限,这是一个可能的“逻辑" 运行时错误。

于 2013-03-21T10:51:11.473 回答
1

从标准草案:

4.5 积分促销

如果 int 可以表示源类型的所有值,则可以将除 bool、char16_t、char32_t 或 wchar_t 的整数转换等级 (4.13) 小于 int 等级的整数类型的纯右值转换为 int 类型的纯右值; 否则,可以将源纯右值转换为 unsigned int 类型的纯右值。

于 2013-03-21T10:55:12.120 回答
1

因为比较unsigned charandunsigned是完全合法的。由于循环计数器明显溢出,问题才开始出现,但我不确定编译器是否会那么聪明

于 2013-03-21T10:53:35.640 回答