2009-09-01 40 views
1

我有一個小樣本函數:如何強制類型轉換文字用C

#define VALUE 0 

int test(unsigned char x) { 
    if (x>=VALUE) 
    return 0; 
    else 
    return 1; 
} 

我的編譯器警告我說的比較(X> = VALUE)在所有情況下是真實的,哪些是對的,因爲X是一個無符號的字符和值與值0定義所以我改變了我的代碼:

if (((signed int) x) >= ((signed int) VALUE)) 

但警告再來。我測試了三個GCC版本(所有版本> 4.0,有時您必須啓用-Wextra)。

在改變的情況下,我有這個明確的轉換,它應該是一個有符號的int比較。爲什麼它聲稱比較總是正確的?

+0

那麼,你想完成什麼?你想在什麼條件下返回1而不是0? – 2009-09-01 13:21:54

+0

我的意圖是擺脫這個警告。 – 2009-09-01 13:31:10

+3

不要擺脫這個警告,試圖擺脫你需要知道一個無符號是否大於等於0.它總是 - 這就是編譯器告訴你的。 – xtofl 2009-09-01 13:35:25

回答

9

即使對於演員來說,在所有已定義行爲的情況下,比較依然如此。編譯器仍然確定(signed int)0的值爲0,並且如果程序具有已定義的行爲(如果該值超出簽名類型的範圍,則從unsigned到signed的轉換未定義)仍然確定(signed int)x)爲非負數。

所以編譯器會繼續發出警告,因爲它會繼續消除else情況。

編輯:沉默警告,編寫代碼爲

#define VALUE 0 

int test(unsigned char x) { 
#if VALUE==0 
    return 1; 
#else 
    return x>=VALUE; 
#endif 
} 
+0

一個'unsigned char'值可能永遠不會超出'signed int'的範圍。即使符號位已設置,該值也在「signed int」的範圍內,並且操作始終定義良好(並且結果始終爲正值)。 – 2009-09-01 13:22:43

+0

糟糕,我錯過了它是從char到int。儘管如此,這可能發生在sizeof(int)== 1的C(理論)實現上。由於int必須至少有2個八位字節,所以在一個字符也是兩個八位字節的實現中這是可能的。我同意在現實的平臺上,這裏不會發生溢出。 – 2009-09-01 13:37:54

1

VALUE0#define意味着你的功能降低這樣:

int test(unsigned char x) { 
    if (x>=0) 
    return 0; 
    else 
    return 1; 
} 

由於x總是傳遞作爲unsigned char,那麼它將永遠有0255包容性之間的值,而不管是否在if聲明中將x0轉換爲signed int。編譯器因此警告您,x將始終大於或等於0,並且else子句永遠無法到達。

11

我認爲GCC是在這種情況下

3

xunsigned char比你聰明,這意味着它是0和256之間由於int大於char,因此鑄造unsigned charsigned int仍保留char的原始值。由於此值始終> = 0,因此您的if始終爲真。

1

unsigned char的所有值都可以在您的int中完美呈現,因此即使是演員陣容,您也永遠不會得到負值。您需要的演員陣容是signed char - 但是,在這種情況下,您應該在功能簽名中聲明xsigned。對客戶說謊是沒有意義的,你需要一個無符號的值,而實際上你需要一個有符號的值。