我对以下2个代码段有疑问。
我在64位计算机上运行此代码(x86_64-linux-gnu)。当数据类型为Val
时,我可以看到值unsigned integer
溢出。
#include<stdio.h>
main()
{
unsigned int Val = 0xFFFFFFFF-15, Val2 = 0xFFFFFFFF;
if (Val+16 < Val2)
{
printf("Val is less than Val2\n");
}
}
如果数据类型为unsigned char
,则不会溢出。
#include<stdio.h>
main()
{
unsigned char Val = 0xFF-15, Val2 = 0xFF;
if (Val+16 < Val2)
{
printf("Val is less than Val2\n");
}
}
我有两个问题:
- 当数据类型为unsigned char时,值
Val
是否会被提升为高数据类型?- 如果是,为什么不将它从32位升级到64位
醇>unsigned long
?
答案 0 :(得分:6)
C11标准说明如下(C11 6.3.11p2.2):
如果
int
可以表示原始类型的所有值(受宽度限制,对于位字段),则该值将转换为int
;否则,它将转换为unsigned int
。这些被称为整数促销。 所有其他类型的整数促销都不会更改。
因此:
unsigned char
将被宣传 - 但是int
是否可以代表unsigned char
的所有值,这是一个实施细节 - 因此可能会提升为unsigned int
在那些平台上。你的不是这些平台之一,因此你的第二个比较是(int)Val + 16 < (int)Val2
。
作为引用段落的最后一句话,unsigned int
永远不会被提升。由于算法是在第一个片段中的无符号整数上完成的,因此0xFFFFFFFF - 15 + 16
的结果在具有32位无符号整数的计算机上为0U
。
答案 1 :(得分:2)
是的,在第二种情况下,数字会提升为int
。如果您修改代码:
#include<stdio.h>
int main()
{
unsigned char Val = 0xFF-15, Val2 = 0xFF;
if ((unsigned char)(Val+16) < Val2)
{
printf("Val is less than Val2\n");
}
}
您将获得您期望的行为。