2017-04-24 21 views
5

我已经从低于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"); 
    } 
} 

我有两个问题:

  1. 是否值Val得到提升到高的数据类型,数据类型是无符号的字符?
  2. 如果是的话,为什么没有得到它从32位提升到64位unsigned long
+8

这不是90年代 - 现在需要'main'上的返回类型。 – InternetAussie

+0

当进行算术运算时,如果可以适用,所有内容都会被提升为“int”,否则所有内容都会被提升为“unsigned int”。这些类型的大小是特定于您的编译器的,您可以轻松找到它。 –

回答

6

的C11标准说以下(C11 6.3.11p2.2):

如果int可以表示原始类型的所有的值(由宽度为受限制,对于一个比特字段),该值被转换为int;否则,它将转换为unsigned int。这些被称为整数促销。 所有其他类型均不受整数升级的影响。

这样:

  1. unsigned char将晋升 - 但它是一个实现细节int是否能代表unsigned char所有值 - 所以它可能被提升到在这些平台上的unsigned int。你们是不是这些平台之一,因此你的第二个比较是(int)Val + 16 < (int)Val2

  2. 为引用的段落的最后一句讲述,一个unsigned int永远不会提升。由于算术是在第一个片段的无符号整数上完成的,因此0xFFFFFFFF - 15 + 16的结果在具有32位值的无符号整数的计算机上的结果为0U

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"); 
    } 
} 

你会得到你期望的行为。

+0

谢谢大家。现在非常清楚。 –