2013-03-21 88 views
5

我難以理解,爲什麼下面的代碼不會警告:警告缺乏對循環計數器

unsigned test = 0xffffffff; 

for (unsigned char i = 0; i < test; i++) 
{ 
    // Some code 
} 

這是在Visual Studio 2010中,但GCC顯然沒有任何警告。有人知道爲什麼

+0

顯示您的構建標誌,您要求什麼警告? – unwind 2013-03-21 10:49:30

+1

因爲不是警告是默認行爲,所以需要爲*警告提出一個案例* – Jon 2013-03-21 10:49:58

+0

如果您將'test'標記爲'const',則會出現警告。 – mitchnull 2013-03-21 12:55:20

回答

6

從語言的角度來看,沒有什麼可警告的。在評估<之前,i被提升爲unsigned int。它完美定義爲增加一個unsigned char,使其繞回到零。

事實上,這段代碼做了一些令人惱火的事情是不幸的。但目前還不清楚編譯器需要應用什麼規則才能檢測出這類事情。

由於在下面的評論@unwind:你可以得到GCC警告的事實,使用-Wtype-limits標誌這個比較必須始終爲true。

更新2:顯然上面的選項在這種情況下無法正常工作(我沒有GCC的「現代版」,現在出手...)

+0

啊..當然!謝謝。 – 2013-03-21 10:52:10

+1

GCC發出警告(['-Wtype-limits'](http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wtype_002dlimits-411)),它警告始終進行真正的比較,我想這在這裏適用。 – unwind 2013-03-21 10:56:08

+0

@unwind:這是一個很好的觀點;真正的問題是比較必須始終評估爲真。 – 2013-03-21 10:58:49

1

i被晉升爲unsigned然後與test進行比較。這裏沒有問題。好。我++會溢出字符,但這是一個運行時問題。我的意思是,在255之後它將是0,也可能不是作者所期望的,如果沒有其他形式的終止它(循環,回退等),使得循環潛力無限。這是一個可能的「邏輯「運行時錯誤。

+0

*「i ++會溢出字符,但這是一個運行時問題。」* - '''不會*溢出,所以沒有運行時問題。 – 2013-03-21 11:25:02

+0

@Christian Rau當然,我的意思是255之後它會是0,也可能不是作者所期望的,使得如果沒有其他的終止循環(休息,回退等等),循環有可能是無限的)這是一個可能的「邏輯」運行時錯誤。 – qPCR4vir 2013-03-21 11:32:59

1

因爲比較unsigned charunsigned是完全合法的。由於循環計數器明顯溢出,問題纔開始顯現,但我不確定編譯器是否會是that smart

+0

*「由於循環計數器明顯溢出,問題纔開始顯現,但我不確定編譯器是否聰明。」* - 編譯器不需要那麼聰明,因爲這甚至不是問題因爲無符號類型永遠不會溢出。 – 2013-03-21 11:23:53

+1

那麼,循環計數器只是在255之後迴繞,有效地創建一個無限循環。這就是我的意思......我認爲恰當的詞是* carry *。 – 2013-03-21 11:28:30

+0

是的,但這不是一個需要診斷的實際問題,因爲只有程序員甚至可以定義這是否應該發生。這並不是說編譯器在分析時發現這個「問題」*太愚蠢或不好。他根本不應該考慮這一點。 – 2013-03-21 11:45:55

1

從標準草案:

4.5積分優惠

比BOOL,char16_t,char32_t,或wchar_t的其整 轉換秩以外的整數類型的prvalue(4.13)小於如果int可以代表 源類型的所有值,則可以將int的等級轉換爲int類型的prvalue;否則,可以將源prvalue轉換爲類型爲unsigned int的前值 。