4 回答

TA貢獻1946條經驗 獲得超3個贊
這是我之前的答案的后續內容,包含C ++ 11相關資料。。
先修課程:關系(數學)的基礎知識。
在C ++ 11中沒有序列點是真的嗎?
是! 這是非常正確的。
序列點已被C ++ 11中的Sequenced Before和Sequenced After(以及Unsequenced和Indeterminately Sequenced)關系所取代。
究竟是什么'之前排序'的事情?
排序之前(§1.9/ 13)是一種關系,它是:
在由單個線程執行的評估之間并引發嚴格的部分順序1
正式它意味著給定任意兩個評價(見下文) A
和B
,如果A
是之前測序 B
,則執行A
應當先執行B
。如果A
之前沒有進行測序B
和B
之前沒有進行測序A
,然后A
和B
在未測序 2。
評價A
和B
被不定測序或者當A
前進行測序B
或B
之前測序A
,但它是未指定的,其3。
[注釋]
1:嚴格偏序是一個二元關系 "<"
在一組P
其是asymmetric
,和transitive
的,即,對于所有的a
,b
以及c
在P
中,我們有:
........(I)。如果a <b則?(b <a)(asymmetry
);
........(II)。如果a <b且b <c則a <c(transitivity
)。
2:未經測試的評估的執行可能重疊。
3:不確定順序的評估不能重疊,但可以先執行。
在C ++ 11的上下文中,“評估”一詞的含義是什么?
在C ++ 11中,表達式(或子表達式)的評估通常包括:
值計算(包括確定glvalue評估對象的標識并獲取先前分配給對象以進行prvalue評估的值)和
引發副作用。
現在(§1.9/ 14)說:
一個完整的表達相關聯的每個值的計算和副作用測序之前與相關聯的每一個值的計算和副作用進行評估下一個完整表達。
瑣碎的例子:
int x;
x = 10;
++x;
在計算值和副作用之后,對與之相關
++x
的值計算和副作用進行排序x = 10;
因此,未定義行為與上述事物之間必然存在某種關系,對吧?
是! 對。
在(§1.9/ 15)中已經提到過
除非另有說明,否則對個體操作員的操作數和個別表達式的子表達式的評估是不確定的4。
例如 :
int main(){ int num = 19 ; num = (num << 3) + (num >> 3);}
對操作
+
員的操作數的評估相對于彼此是不確定的。對操作數
<<
和>>
操作符的評估相對于彼此是不確定的。
4:在一個程序的執行過程中被評估一次以上的表達,未測序和不定測序其子表達式的評估不需要在不同的評價一致的方式進行。
(§1.9/ 15)運算符操作數的值計算在運算符結果的值計算之前排序。
這意味著在x + y
值計算之前,x
并且y
在計算值之前對其進行排序(x + y)
。
更重要的是
(§1.9/ 15)如果對標量物體的副作用相對于其中任何一個都沒有排序
(a)對同一標量物體的另一個副作用
要么
(b)使用相同標量對象的值進行值計算。
行為未定義。
例子:
int i = 5, v[10] = { };void f(int, int);
i = i++ * ++i; // Undefined Behaviour
i = ++i + i++; // Undefined Behaviour
i = ++i + ++i; // Undefined Behaviour
i = v[i++]; // Undefined Behaviour
i = v[++i]: // Well-defined Behavior
i = i++ + 1; // Undefined Behaviour
i = ++i + 1; // Well-defined Behaviour
++++i; // Well-defined Behaviour
f(i = -1, i = -1); // Undefined Behaviour (see below)
當調用函數(函數是否為內聯函數)時,與任何參數表達式相關聯的每個值計算和副作用,或者使用指定被調用函數的后綴表達式,都會在執行每個表達式或語句之前對其進行排序。叫功能。[ 注意: 與不同參數表達式相關的值計算和副作用未被排序。- 結束說明 ]
表達式(5)
,(7)
而(8)
不要調用未定義的行為。有關更詳細的說明,請查看以下答案。
最后的說明:
如果您發現帖子中有任何缺陷,請發表評論。高級用戶(代表> 20000)請不要猶豫,編輯帖子以糾正拼寫錯誤和其他錯誤。

TA貢獻1848條經驗 獲得超10個贊
我猜這個改變有一個根本原因,讓舊的解釋更清晰,不僅僅是裝飾性的:原因是并發性。未指定的細化順序僅僅是選擇幾個可能的連續排序中的一個,這與排序之前和之后完全不同,因為如果沒有指定的排序,則可以進行并發評估:舊規則不是這樣。例如:
f (a,b)
先前要么是b,要么是b,然后是a。現在,可以使用交錯的指令或甚至在不同的核上評估a和b。

TA貢獻1829條經驗 獲得超9個贊
在C99(ISO/IEC 9899:TC3)
這似乎從這個討論迄今以下steteents是關于及其評價問題作了缺席。
[...]子表達式的評估順序和副作用發生的順序都是未指定的。(第6.5節第67頁)
操作數的評估順序未指定。如果嘗試修改賦值運算符的結果或在下一個序列點之后訪問它,則行為[sic]未定義。(第6.5.16節第91頁)
- 4 回答
- 0 關注
- 833 瀏覽
添加回答
舉報