亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

未定義的行為和序列點

未定義的行為和序列點

大話西游666 2019-05-20 16:51:30
什么是“序列點”?未定義的行為和序列點之間的關系是什么?我經常使用有趣和復雜的表達方式a[++i] = i;,讓自己感覺更好。我為什么要停止使用它們?如果您已閱讀此內容,請務必訪問后續問題重新加載未定義的行為和序列點。
查看完整描述

4 回答

?
智慧大石

TA貢獻1946條經驗 獲得超3個贊

這是我之前的答案的后續內容,包含C ++ 11相關資料。。


先修課程:關系(數學)的基礎知識。


在C ++ 11中沒有序列點是真的嗎?

是! 這是非常正確的。

序列點已被C ++ 11中的Sequenced BeforeSequenced After(以及UnsequencedIndeterminately Sequenced關系所取代。


究竟是什么'之前排序'的事情?

排序之前(§1.9/ 13)是一種關系,它是:

在由單個線程執行的評估之間并引發嚴格的部分順序1

正式它意味著給定任意兩個評價(見下文) AB,如果A之前測序 B,則執行A 應當先執行B。如果A之前沒有進行測序BB之前沒有進行測序A,然后AB未測序 2。

評價AB不定測序或者當A前進行測序BB之前測序A,但它是未指定的,其3。

[注釋] 
1:嚴格偏序是一個二元關系 "<"在一組P其是asymmetric,和transitive的,即,對于所有的a,b以及cP中,我們有:
........(I)。如果a <b則?(b <a)(asymmetry); 
........(II)。如果a <b且b <c則a <c(transitivity)。
2:未經測試的評估的執行可能重疊。
3:不確定順序的評估不能重疊,但可以先執行。


在C ++ 11的上下文中,“評估”一詞的含義是什么?

在C ++ 11中,表達式(或子表達式)的評估通常包括:

現在(§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);}
  1. 對操作+員的操作數的評估相對于彼此是不確定的。

  2. 對操作數<<>>操作符的評估相對于彼此是不確定的。

4:在一個程序的執行過程中被評估一次以上的表達,未測序不定測序其子表達式的評估不需要在不同的評價一致的方式進行。

(§1.9/ 15)運算符操作數的值計算在運算符結果的值計算之前排序。

這意味著在x + y值計算之前,x并且y在計算值之前對其進行排序(x + y)。

更重要的是

(§1.9/ 15)如果對標量物體的副作用相對于其中任何一個都沒有排序

(a)對同一標量物體的另一個副作用

要么

(b)使用相同標量對象的值進行值計算。

行為未定義。

例子:

int i = 5, v[10] = { };void  f(int,  int);
  1. i = i++ * ++i;  // Undefined Behaviour

  2. i = ++i + i++;  // Undefined Behaviour

  3. i = ++i + ++i;  // Undefined Behaviour

  4. i = v[i++];     // Undefined Behaviour

  5. i = v[++i]:     // Well-defined Behavior

  6. i = i++ + 1;    // Undefined Behaviour

  7. i = ++i + 1;    // Well-defined Behaviour

  8. ++++i;          // Well-defined Behaviour

  9. f(i = -1, i = -1); // Undefined Behaviour (see below)

當調用函數(函數是否為內聯函數)時,與任何參數表達式相關聯的每個值計算和副作用,或者使用指定被調用函數的后綴表達式,都會在執行每個表達式或語句之前對其進行排序。叫功能。[ 注意: 與不同參數表達式相關的值計算和副作用未被排序。- 結束說明 ]

表達式(5)(7)(8)不要調用未定義的行為。有關更詳細的說明,請查看以下答案。


最后的說明

如果您發現帖子中有任何缺陷,請發表評論。高級用戶(代表> 20000)請不要猶豫,編輯帖子以糾正拼寫錯誤和其他錯誤。


查看完整回答
反對 回復 2019-05-20
?
慕桂英546537

TA貢獻1848條經驗 獲得超10個贊

我猜這個改變有一個根本原因,讓舊的解釋更清晰,不僅僅是裝飾性的:原因是并發性。未指定的細化順序僅僅是選擇幾個可能的連續排序中的一個,這與排序之前和之后完全不同,因為如果沒有指定的排序,則可以進行并發評估:舊規則不是這樣。例如:

f (a,b)

先前要么是b,要么是b,然后是a。現在,可以使用交錯的指令或甚至在不同的核上評估a和b。


查看完整回答
反對 回復 2019-05-20
?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

C99(ISO/IEC 9899:TC3)這似乎從這個討論迄今以下steteents是關于及其評價問題作了缺席。

[...]子表達式的評估順序和副作用發生的順序都是未指定的。(第6.5節第67頁)

操作數的評估順序未指定。如果嘗試修改賦值運算符的結果或在下一個序列點之后訪問它,則行為[sic]未定義。(第6.5.16節第91頁)


查看完整回答
反對 回復 2019-05-20
  • 4 回答
  • 0 關注
  • 833 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號