[英]Is conversion from unsigned to signed undefined?
void fun(){
signed int a=-5;
unsigned int b=-5;
printf("the value of b is %u\n",b);
if(a==b)
printf("same\n");
else
printf("diff");
}
它是印刷:
4294967291
相同
在第二行中,有符号值转换为无符号值。 所以b的值为UINTMAX + 1 - 5 = 4294967291。
我的问题是比较操作中发生了什么。
1)是否再次转换为无符号并与b进行比较?
2)b(即无符号)是否会被转换为有符号值并自动进行比较?
3)由于int溢出,是否从unsigned转换为signed undefined?
我已阅读有关该主题的其他帖子。 我只想澄清问题2和问题3。
1)是否再次转换为无符号并与b进行比较?
是。 在表达式(a == b)中,发生称为“平衡”的隐式类型转换(正式名称是“通常的算术转换”)。 平衡规则指定如果比较具有相同大小和类型的有符号和无符号操作数,则将带符号的操作数转换为无符号操作数。
2)b(即无符号)是否会被转换为有符号值并自动进行比较?
不,它永远不会转换为您的示例中的签名。
3)由于int溢出,是否从unsigned转换为signed undefined?
这就是标准所说的:(C11)
6.3.1.3有符号和无符号整数
1当具有整数类型的值转换为除_Bool之外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。
2否则,如果新类型是无符号的,则通过重复加或减一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。
3否则,新类型已签名且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号。
换句话说,如果编译器可以设法在上面的2)中进行转换,那么行为是明确定义的。 如果不能,则结果取决于编译器实现。
它不是未定义的行为。
回答:
a
转换为unsigned int
。 a
的范围比b
的签名对应范围更宽(我可以想象long long a
可以做), b
将被转换为带符号的类型。 b = -5;
这算作溢出并且是未定义的行为。 比较signed
与unsigned
将自动提升操作数unsigned
。 - 如果出现溢出,你会发现自己再次遇到未定义的行为.-明显错误,请参阅 下面的 [编辑]
另见http://c-faq.com/expr/preservingrules.html 。
[edit] 更正 - 标准确实声明在从负签名转换为无签名时应使用2补码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.