我试图理解为什么以下代码不在指定位置发出警告。
//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;
我以为这与后台推广有关,但最后两个似乎不是这么说的。
在我看来,第一个==
比较与其他比较一样是有符号/无符号不匹配吗?
当比较有符号和无符号时,编译器将有符号值转换为无符号值。为了平等,这并不重要,-1 == (unsigned) -1
。对于其他比较很重要,例如以下是正确的:-1 > 2U
.
编辑:参考资料:
5/9:(表达)
许多二元运算符期望
算术或枚举操作数
类型导致转换和产量
结果类型以类似的方式。这
目的是产生一个通用类型,
这也是结果的类型。
这种模式称为通常模式
算术转换,即
定义如下:
- 如果其中之一
操作数的类型为 long double,
其他应转换为长
双倍的。
- 否则,如果任一操作数
是双倍,另一个是
转换为双倍。
- 否则,如果
一个操作数是 float,另一个是 float
应转换为浮点数。
- 否则积分优惠
(4.5) 应同时执行
操作数.54)
- 那么,如果任一操作数
是无符号长,另一个应是
转换为无符号长整型。
- 否则,如果一个操作数是 long
int 和另一个无符号 int,然后
如果一个long int可以代表所有
unsigned int 的值,
unsigned int 应转换为
长整型;否则两个操作数
应转换为 unsigned long
国际。
- 否则,如果任一操作数是
long,另一个应转换为
长的。
- 否则,如果任一操作数
未签名的,其他应为
转换为无符号。
4.7/2:(积分转换)
If the destination type is unsigned,
the resulting value is the least
unsigned integer congruent to the
source integer (modulo 2n where n is
the number of bits used to represent
the unsigned type). [Note: In a two’s
complement representation, this
conversion is conceptual and there is
no change in the bit pattern (if there
is no truncation). ]
EDIT2:MSVC 警告级别
MSVC的不同警告级别所警告的内容当然是开发者做出的选择。在我看来,他们在有符号/无符号相等与更大/更少比较方面的选择是有意义的,当然这完全是主观的:
-1 == -1
意思是一样的-1 == (unsigned) -1
- 我发现这是一个直观的结果。
-1 < 2
does not意思是一样的-1 < (unsigned) 2
- 乍一看不太直观,IMO 值得“更早”警告。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)