2016-09-26 74 views
2

爲什麼在gcc中編譯下面的代碼不會產生任何類型不匹配警告? -1INT類型,f()預計鍵入字符爲什麼gcc不會爲int和char產生類型不匹配的警告?

void f(char c) {} 
int main(void) 
{ 
    f(-1); 
    return 0; 
} 

即使我們明確地指定類型,也沒有警告:

void f(unsigned char c) {} 
int main(void) 
{ 
    f((signed int)-1); 
    return 0; 
} 

什麼奇怪的是:如果我們指定超出範圍值時,將顯示警告:

void f(char c) {} 
int main(void) 
{ 
    f(65535); 
    return 0; 
} 

warning: overflow in implicit constant conversion

gcc版本6.1.1

+0

如果使該功能非空,會發生什麼情況? – talonmies

+0

@talonmies void f(...){c ='x'; }' - 沒有區別 –

+0

那麼,看看警告,「在隱式常量轉換中溢出」。你的第一個例子有溢出嗎?如果沒有,爲什麼編譯器會警告某些不存在的東西。 – hyde

回答

1

好像在GCC的Wconversion警告選項中的缺陷。

如果啓用,此警告選項警告的任務:

int i = c; //where c is of type char 

並傳遞變量函數:

f(i); //where i is of type int 

,但不警告傳遞整數文字:

f(-1); //where -1 is of type int 

根據C標準,最後一個例子也應該產生警告。

gcc的是足夠聰明的整數字面擬合認識到一個char類型,並且不會發出警告,而如果使用不適合的值,但它警告。

這是合理的行爲,雖然迂腐用戶將除應當由鑄造沉默鍵入字符的最後一個例子警告。

的gcc實際上包括警告選項時的整數類型的標誌是通過隱式轉換改變爲警告。使用:-WSign-conversion,你會得到第二個例子的警告。

+0

應該在哪裏報告錯誤? –

+0

@IgorLiferenko我敢說gcc開發人員不會考慮這個bug。這是合理的行爲,即更多的用戶會因變化而感到不便,而不是。 – 2501

+0

'-1'如何適合'unsigned char'類型(範圍從0到255)? –

5

int可以轉換爲一個char。允許在C和C++中將int轉換爲char

從C11標準:

6.3.1.3符號和無符號整數

1當與整數類型的值被轉換爲比其它_Bool另一個整數類型,如果該值可以是由新型代表,它沒有改變。 2否則,如果新類型是無符號的,則通過反覆添加或減去比新類型中可以表示的最大值多一個值來轉換該值,直到該值處於新類型的範圍內爲止。

3否則,新類型將被簽名且值不能在其中表示;結果是實現定義的或實現定義的信號被引發。

從C++ 11標準:

4.7積分轉換

1的整數類型的prvalue可以被轉換成另一種整數類型的prvalue。非範型枚舉類型的值可以轉換爲整數類型的prvalue。

2如果目標類型爲無符號的,所得到的值是至少無符號整數全等到源 整數...

3如果目標類型有符號,則該值是不變的,如果它可以被表示在目標類型(和位域寬度)中;否則,該值是實現定義的。

如果char是一個有符號的類型,它可以很容易地保存值-1。因此,這種行爲是可以預測的。 cf中的整數值將是-1。當使用unsigned char時,c的值將是實現定義的值,但在兩個標準下仍然允許。

+0

是C標準一樣C++標準? –

+1

@IgorLiferenko,它不一樣,但他們密切關注這些規則。 –

+0

我明確指定'unsigned char',但沒有打印警告。請解釋'unsigned char'如何保存值'-1'。 –

相關問題