2017-04-24 46 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

謝謝大家。現在非常清楚。 –