我很难理解为什么以下代码没有警告:
unsigned test = 0xffffffff;
for (unsigned char i = 0; i < test; i++)
{
// Some code
}
这是在 Visual Studio 2010 上,但 GCC 显然也没有警告。有谁知道为什么?
我很难理解为什么以下代码没有警告:
unsigned test = 0xffffffff;
for (unsigned char i = 0; i < test; i++)
{
// Some code
}
这是在 Visual Studio 2010 上,但 GCC 显然也没有警告。有谁知道为什么?
从语言的角度来看,没有什么可警告的。 在评估之前i
被提升到。并且它是完全明确定义的,它增加一个这样它环绕到零。unsigned int
<
unsigned char
不幸的是,这段代码做了一些令人讨厌的事情。但目前尚不清楚编译器需要应用什么规则才能检测到这类事情。
感谢下面评论中的@unwind:您可以让 GCC 警告这样一个事实,即该比较必须始终使用-Wtype-limits
标志评估为真。
更新 2:显然上述选项在这种情况下不起作用(我现在手头没有“现代”版本的 GCC ......)
i
被提升到unsigned
,然后与 比较test
。这里没有问题。出色地。i++ 会溢出字符,但这是一个运行时问题。我的意思是,在 255 之后它将为 0,这可能不是作者所期望的,如果没有其他形式的终止它(中断、重新调整等),则使循环可能无限,这是一个可能的“逻辑" 运行时错误。
从标准草案:
4.5 积分促销
如果 int 可以表示源类型的所有值,则可以将除 bool、char16_t、char32_t 或 wchar_t 的整数转换等级 (4.13) 小于 int 等级的整数类型的纯右值转换为 int 类型的纯右值; 否则,可以将源纯右值转换为 unsigned int 类型的纯右值。
因为比较unsigned char
andunsigned
是完全合法的。由于循环计数器明显溢出,问题才开始出现,但我不确定编译器是否会那么聪明。