2015-10-13 48 views
3

我想了解整數提升如何與算術移位運算符一起工作。特別是,我想知道,a, b, c, d, e, f, g, h的哪些值是根據C++ 14標準精確定義的,哪些可以取決於平臺/硬件/編譯器(假設爲sizeof(int) == 4)。布爾型左移和右移

int a = true << 3; 
int b = true >> 3; 

int c = true << 3U; 
int d = true >> 3U; 

int e = true << 31; 
int f = true >> 31; 

int g = true << 31U; 
int h = true >> 31U; 
+0

可能的重複:[使用位運算符爲布爾](http://stackoverflow.com/questions/24542/using-bitwise-operators-for-booleans-in-c) –

+0

@ThomasMatthews你鏈接的問題不說話關於偏移。 – Winter

回答

2

從[expr.shift]:

結果類型的是,促進了左操作數。如果右操作數 爲負數,或者大於或等於升級的左操作數的位長度,則行爲未定義。

移位bool的結果類型總是int,無論右側是什麼。我們永遠不會移位至少32位或負數,所以我們在所有賬戶中都可以。

爲左位移(E1 < < E2):

否則,如果E1有一個簽名的類型和非負值,E1×2 E2是在相應的無符號可表示 類型的結果類型,那麼轉換爲結果類型的值就是結果值;否則,行爲是不確定的。

1×2 是unsigned int表示的,這就是我們正在做的最大的左移,所以我們確定那裏的所有賬戶了。

對於右移(E1 >> E2):

如果E1有一個簽名的類型和爲負值,所得到的值是實現定義。

E1永遠不是負面的,所以我們在那裏也可以!任何地方都沒有未定義或實現定義的行爲。

0

以下內容主要是對Barry答案的補充,清楚地解釋了左右移位的規則。

至少FO C++ 11,積分促進一個bool的給出了和1:4.5積分優惠[conv.prom]§6

bool類型的prvalue可以是轉化爲int類型的prvalue,其中false爲零並且爲真。

所以在原來的例子,bdfh都將得到一個0值,ac都得到一個8值:只有完全定義的行爲,直到這裏。

eg將接收的無符號數0x80000000,所以如果你把它的影響爲unsigned int變量會被罰款,但你正在使用符號的32個整數。所以,你得到一個整體轉換:4.7積分轉換[conv.integral]§3

如果目的地是帶符號的價值是不變的,如果它可以在目標類型來表示;否則,該值是實現定義的。所以結果是實施eg定義

和無符號0x80000000的不帶符號的64位整數無法表示。