2015-04-22 17 views
9

當我編譯用gcc下面的代碼:-Wconversion警告

int main() 
{ 
    unsigned char c = 1; 
    c <<= 1; // WARNING ON THIS LINE 
    return 0; 
} 

我得到這樣的警告:

conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]

爲什麼?這段代碼有什麼問題?其實,我真的可以在unsigned char變量上使用操作符<<=嗎?

編譯命令:

g++ test.cpp -Wconversion -o test.exe

+1

對我來說,這對於編譯器編寫者和用戶來說都是那些「該死的,如果你做了,該死的,如果你沒有」的情況。作爲一個用戶,你寫的是乾淨的,併產生預期的答案,通常是完全可以接受的。它並不需要額外的語言混亂,使其更難理解。作爲一名編譯器編寫者,技術上存在縮小的轉換,所以警告在技術上是正確的。但我不禁覺得,在這種情況下,或者類似的涉及「短」(這可能會引發警告),這種警告實際上並不具有建設性。 –

回答

8

這是一個有效的警告:

c <<= 1; 

等同於:

c = c << 1 

和規則<<表示操作數被提升,在這種情況下將被提升到int,結果是升級類型。因此,最終會出現從intunsigned char的轉換,這可能導致價值改變。

該代碼是有效的,該警告告訴您隱式轉換正在發生,並且在某些情況下轉換可能會改變該值。使用演員將會使警告消失。隱式轉換的結果可能非常不直觀,並且在某些情況下未定義的行爲。請參閱gcc Wconversion wiki for some details

我沒有看到一個方法來消除警告而不出手動擴大經營和使用static_cast

c = static_cast<unsigned char>(c << 1); 

我們可以從長螺紋看到這個gcc bug report不是每個人都認爲這是一個此警告的有用案例。

對於從draft C++ standard5.8移位運算符參考:

的操作數應爲整體的或無作用域枚舉類型和積分促銷被執行。結果類型的是,促進了左操作數[...]

和從部分5.17分配和複合賦值運算符:

形式E1運算的表達式的行爲= E2相當於E1 = E1 op E2,只不過E1是 只評估一次。 [...]

+1

我也有問題,如果做'c << = static_cast (1);'。那麼你是否說C++中沒有一個字節類型的移位運算符? : -/ – Caduchon

+4

請參閱[在C和C++的算術運算之前爲什麼必須將短整型轉換爲int](http://stackoverflow.com/q/2437186​​8/1708801),以獲取有關操作數被提升爲更寬類型的基本原理。主要是因爲它導致更快的生成代碼。 –