2016-11-29 81 views
0

我發現,VisualStudio 2015堅持要將WORDunsigned short)提升爲unsigned int,因爲只有WORD值只涉及位操作。 (即當做16位| 16位時將16位提升爲32位)。如何避免按位運算的整數提升

例如

// where WORD is a 'unsigned short' 
const WORD kFlag = 1; 
WORD old = 2; 
auto value = old | kFlag; // why the blazes is value an unsigned int (32 bits) 

此外,有沒有辦法獲得0x86 intrinsics爲WORD|WORD?我當然不想支付(16-> 32 | 16 - >) - > 16。此代碼也不需要消耗多於16位的寄存器,而不是少於32位的寄存器。

但註冊表的使用真的只是一個旁觀。只要結果與我無法區分,優化器可以隨心所欲地執行。 (即它不應以可見的方式改變尺寸)。

對我來說,主要問題是使用flags | kFlagValue會導致更廣泛的實體,然後將其抽入模板會導致類型不匹配錯誤(模板比我想要進入的時間長得多,但是點是它需要兩個參數,並且它們應該匹配類型,或者可以輕易轉換,但不是,由於這個自動大小提升規則)。

如果我獲得了「保守位處理功能設置」,然後我可以使用:

 flag non-promoting-bit-operator kFlagValue 

爲了實現我的目的。

我想我必須去寫那個,或者因爲這個不幸的規則而使用到處都是。

在這種情況下,C++不應該提升。這是一種糟糕的語言選擇。

+0

如果此函數的輸出對於程序的整體執行非常重要,那麼請務必在其中放置一些彙編程序,並幫助編譯器正確執行。否則,如果它仍然口感好,爲什麼要擔心香腸裏有什麼? –

+0

因爲它違反了類型。 C++正在拓寬不應該更廣泛的東西。與其他16位值進行或「或」運算和「與」運算的16位值將永遠不會溢出,並且結果是100%安全的16位值,可存儲在ABI中。我不希望語​​言以任何方式促進事物的速度,在不需要任何東西的情況下產生明顯的副作用(如果它想這樣做是我看不見的優化,那很好,但是這具有明顯的後果)強制我的代碼必須改變):( – Mordachai

+1

邏輯運算,算術運算的一個子集,如果你將值聲明爲WORD,那麼編譯器可能會優化它,將小於'int'的操作數轉換爲'int' – doug

回答

1

爲什麼value提升爲更大的類型?因爲語言規範說它是(一個16位的unsigned short將被轉換爲一個32位的int)。 x86上的16位操作實際上會因相應的32位操作而受到懲罰(由於前綴操作碼),所以32位版本可能運行得更快。

+0

擊敗我 - 小型操作在較大的CPU上往往更昂貴。 –

+0

如果要遵循規範(在OP的環境中),它應該是'int',而不是'unsigned'。「比布爾,char16_t,char32_t,或wchar_t的其整轉換 秩(4.13)以外的整數類型的prvalue小於INT的秩可以被轉換成一個int類型的prvalue如果INT可以表示所有 值源類型;否則,源prvalue可以轉換爲類型爲unsigned int的prvalue。 – krzaq

+0

我不關心促銷的標誌 - 而是促銷本身。 我可以看到有+/-促進,但位操作員只是惱人的,迫使我與無意義的鑄造操作員撒我的代碼。 – Mordachai