我知道,右移負簽名類型取決於實現,但如果我執行左移,該怎麼辦?例如:左和右移負整數定義的行爲?
int i = -1;
i << 1;
這是明確的嗎?
我認爲標準的不說,大約有符號整型負值
如果E1已經簽署的類型和非負值,E1×2 E2是 可表示在結果類型那麼這就是結果的價值; 否則,行爲是不確定的。
它只是澄清,如果結果不能用signed型表示,那麼行爲是未定義的。
我知道,右移負簽名類型取決於實現,但如果我執行左移,該怎麼辦?例如:左和右移負整數定義的行爲?
int i = -1;
i << 1;
這是明確的嗎?
我認爲標準的不說,大約有符號整型負值
如果E1已經簽署的類型和非負值,E1×2 E2是 可表示在結果類型那麼這就是結果的價值; 否則,行爲是不確定的。
它只是澄清,如果結果不能用signed型表示,那麼行爲是未定義的。
你不能正確讀這句話。該標準在以下情況下定義它:左邊的操作數具有帶符號的類型和非負值和結果可表示(以前在同一段落中將其定義爲無符號類型)。在所有其他情況下(注意該句子中的use of the semicolon),即如果這些條件中的任何一條未被驗證,則行爲是不確定的。
+1以獲得更好的解釋。 – Xeo
+1分號 – Pubby
如果我有一個非負數,並且我右移了太多次,該怎麼辦? 'int i = 1;我>> 24;'這是有效的嗎?只是困惑。 – user103214
否則,行爲是未定義的。
這包括
如果E1有符號類型和非負值
當C標準被編纂時,不同的平臺在左移負整數時會做不同的事情。其中一些行爲可能會觸發特定於實現的陷阱,這些陷阱的行爲可能不在程序的控制範圍之內,並且可能包含隨機代碼執行。儘管如此,爲這些平臺編寫的程序可能會利用這種行爲(例如,程序可能會指定用戶在運行之前必須先做一些配置系統的陷阱處理程序,但程序可以利用適當配置的陷阱處理程序)。 C標準的作者並不想說負值數據左移的機器的編譯器必須進行修改以防止這種陷阱(因爲程序可能會依賴於它),但是如果遺漏的話,允許移動一個負數可以觸發一個可能導致任意行爲(包括隨機代碼執行)的陷阱,這意味着左移一個負數可以做任何事情。因此未定義的行爲。在實踐中,直到大約5年前,爲使用二補數學(意味着自1990年以來製造的機器的99 +%)的機器編寫的編譯器的99 +%將持續產生以下行爲x<<y
和x>>y
,在這種程度上,代碼依賴於這種行爲被認爲不再是不可移植的,而不是假定char
是8位的代碼。 C標準沒有強制要求這樣的行爲,但是任何希望與廣泛的現有代碼兼容的編譯器作者都會遵循它。
y
是有符號類型,x << y
和x >> y
好像y
被摔簽名進行評估。x
is type int
,x<<y
相當於(int)((unsigned)x << y)
。x
is type int
and positive,x>>y
equivalent to (unsigned)x >> y
。如果x
類型爲int
且爲負,則x>>y
等同於〜(〜((無符號)x)>> y)。x
是long
類型,則類似規則適用,但unsigned long
而不是unsigned
。x
是N位型和y
大於N-1時,則和x >> y
x << y
可以任意產生零,或者可以作爲雖然右操作數是y % N
行動;他們可能需要額外的時間與y
成比例[請注意,在32位機器上,如果y
是負數,這可能是一個長時間,雖然我只知道一臺機器,實際上它會運行超過256個額外的步驟]。編譯器在選擇時不一定是一致的,但總會返回其中一個指示值而沒有其他副作用。不幸的是由於某種原因,我不能完全參透,編譯器的編寫者已經決定,而不是允許程序員表示應該使用什麼假設編譯器死代碼去除,編譯器應該假設它是不可能執行的任何變化其行爲不是C標準所要求的。因此,給定代碼如下所示:
uint32_t shiftleft(uint32_t v, uint8_t n)
{
if (n >= 32)
v=0;
return v<<n;
}
編譯器可確定,因爲代碼將接合未定義的行爲,當n爲32或更大時,編譯器可以假定if
絕不會返回true,並且因此可以省略代碼。因此,除非有人提出了C標準才能恢復經典行爲,並允許程序員指定哪些假設值得刪除死代碼,否則不能將此類結構推薦給任何可能饋送到超現代編譯器的代碼。
什麼部分不清楚? *如果* E1具有非負值且... *否則*行爲未定義。 E1具有負值,因此行爲未定義。的確,有時標準可以用一些額外的括號來完全清楚「其他」所指的是什麼,但這裏的意思是「在任何未描述的情況下」。它有助於解釋這些事情時要記住,在標準沒有描述行爲的任何情況下,行爲是不確定的。所以實際上「否則」在形式上是多餘的。 –
@SteveJessop:我認爲__otherwise__表示如果該值不可表示,則行爲未定義。我不確定這是否包括負值的E1。 – user103214
@Norman:確實如此,參見R.Marthinho的回答,有一個分號,在條件和最終結果之間有一個明確的分隔符。 – Xeo