我试图理解为什么下面的代码不会在指定的地方发出警告 .
//from limits.h
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
/* = 0x7fffffff */
int a = INT_MAX;
//_int64 a = INT_MAX; // makes all warnings go away
unsigned int b = UINT_MAX;
bool c = false;
if(a < b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a > b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a <= b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a >= b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a == b) // no warning <--- warning expected here
c = true;
if(((unsigned int)a) == b) // no warning (as expected)
c = true;
if(a == ((int)b)) // no warning (as expected)
c = true;
我认为这与背景推广有关,但最后两个似乎不这么说 .
在我看来,第一个 ==
比较与其他比较一样是签名/未签名的不匹配?
4 回答
在使用2补码(大多数现代处理器)表示值的系统中,即使是二进制形式,它们也是相等的 . 这可能是编译器不抱怨 a == b 的原因 .
对我来说's strange compiler doesn'警告你 a == ((int)b) . 我认为它应该给你一个整数截断警告或其他东西 .
将signed with signed与unsigned进行比较时,编译器会将signed值转换为unsigned . 对于平等,这没关系,
-1 == (unsigned) -1
. 对于其他比较,它很重要,例如以下是真实的:-1 > 2U
.编辑:参考文献:
5/9 :(表达式)
4.7 / 2 :(整体转换)
EDIT2:MSVC警告级别
关于MSVC的不同警告级别的警告当然是开发人员做出的选择 . 正如我所看到的,他们在签名/无符号平等与更大/更少比较相关的选择是有道理的,当然这完全是主观的:
-1 == -1
与-1 == (unsigned) -1
相同 - 我发现这是一个直观的结果 .-1 < 2
与-1 < (unsigned) 2
的含义不同 - 乍一看这不太直观,IMO值得发出"earlier"警告 .为什么签名/未签名警告很重要,程序员必须注意它们,以下示例说明了这一点 .
猜猜这段代码的输出?
输出:
惊讶吗?在线演示:http://www.ideone.com/5iCxY
Bottomline: 相比之下,如果一个操作数是
unsigned
,则另一个操作数被隐式转换为unsigned
if 其类型已签名!==运算符只是进行逐位比较(通过简单除法来查看它是否为0) .
比较小/大的比较更多地依赖于数字的符号 .
4位示例:
1111 = 15?还是-1?
所以,如果你有1111 <0001 ......它的含糊不清......
但如果你有1111 == 1111 ......虽然你不是故意的,但它是一样的 .