2012-06-21 35 views
4

一些信號源同時發現這樣的代碼:檢查如果無符號小於零

void foo(unsigned int i) 
{ 
if(i<0) 
    printf("Less then zero\n"); 
else 
    printf("greater or equ\n"); 
} 

int main() 
{ 
    int bar = -2; 
    foo(bar); 
    return 0; 
} 

,我認爲是沒有意義的,但可能有某些情況下(安全性?),使這個檢查SensAble公司?

+0

謝謝您的回答!你增強了我的信心。但有人寫了這個。可能有一些平臺或編譯器認爲另一種方式? – dtoch

+0

有可能是根據您的系統上int的大小符號/無符號轉換的精確值的一些輕微的變化(見jonnyGold和wap26鏈接到答案)。但是在這種情況下,所有編譯器都會輸出表現出相同控制流行爲的可執行文件。換句話說 - 沒有:)寫這個的人可能沒有注意到這種控制流的情況會發生(一個錯誤),否則他們正在試驗。 – erapert

+0

似乎你是對的。 我做了一些檢查。 GCC只是刪除任何檢查和寫入字符串: 'FOO: pushl%ebp的 MOVL%ESP,EBP% subl $ 24%ESP MOVL $ .LC0,(%ESP) 呼叫提出 離開 ret' 鐺生成檢查,但: 1.無效美孚(無符號整型ⅰ) 直列'FOO + 19:宰0x804841f ' 2.無效美孚(帶符號的int i)以: 直列'FOO + 19:JGE 0x804841f ' – dtoch

回答

13

一個unsigned int不能小於0的定義。所以,爲了更直接地回答你的問題,你認爲這是沒有道理的。它不是一個有意義的安全項目,除非你遇到類似於循環的事情,它意外地將有符號的int遞減到0,然後將其轉換爲無符號整型,以用作數組中的索引,並因此索引數組以外的內存。

+1

[這個答案](http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always-safe)上,當你從一個負值施放發生了什麼光棚在t轉換爲無符號整數。 – bluevector

2

i將始終爲>=0,因爲它被聲明爲unsigned,因此將其解釋爲無符號整數。 所以你的第一次測試將永遠是錯誤的。

您的通話foo(bar)實際上是一個int轉換成unsigned int。這可能會讓你感到困惑。而「轉換」實際上並沒有改變整數的字節/位值,這只是正式的輸入和解釋。

的符號/無符號轉換的例子看到這個answer

下面是一個簡單的例子(確切輸出依賴於unsigned int的字節數在系統上,對我來說是4個字節)。

代碼:

printf("%u\n", (unsigned int) -2); 

輸出:

4294967294