Mik*_*hin 7 c conditional-operator visual-c++
我有以下C代码:
unsigned int a;
unsigned char b, c;
void test(void) {
if (a < b)
return;
if (a < (b ? b : c))
return;
}
Run Code Online (Sandbox Code Playgroud)
当我编译它(使用Microsoft cl,来自MS SDK 7,-W3警告级别)时,第二个比较会发出警告:C4018,签名/无符号不匹配.第一次比较没有发出警告.
我已经在条件运算符上检查了MS文档,并且他们说如果两个操作数是相同的类型,结果将是相同的类型,所以它应该作为第一个比较.我错过了什么吗?
UPD:测试gcc -Wall -Wextra -pedantic并且没有任何警告.
这可能是由于算术转换规则:首先,任何整数类型的转换等级小于int(例如unsigned char)将提升为int或unsigned int.
结果是否将是int或unsigned int不(直接地)依赖于原始类型的符号性,但其范围:int用于即使对于无符号类型,只要所有的值可以被表示,这是的情况下unsigned char对主流架构.
其次,由于两个操作数最终具有相同的转换等级,但是一个是无符号的,另一个操作数也将转换为无符号类型.
在语义上,您的表达式读取
a < (unsigned int)(int)b
Run Code Online (Sandbox Code Playgroud)
和
a < (unsigned int)(b ? (int)b : (int)c)
Run Code Online (Sandbox Code Playgroud)
编译器显然足够聪明,可以注意到第一种情况不会导致问题,但第二种情况则失败.
Steve Jessop的评论很好地解释了这可能发生的原因:
我想在第一种情况下,编译器认为,"我有一个比较运算符,其操作数类型是
unsigned int和unsigned char.不需要警告,现在让我们应用促销,然后进行常规转换".在第二种情况下,它认为,"我有一个比较运算符,其操作数类型是
unsigned int和int(我作为RHS上的条件表达式的类型导出).最好警告那个!".