簡體   English   中英

賦值子表達式的評估順序

[英]Order of evaluation of assignment subexpressions

C ++ 11標准 (5.17,expr.ass)表明了這一點

在所有情況下,在右和左操作數的值計算之后,以及在賦值表達式的值計算之前,對賦值進行排序。 對於不確定序列的函數調用,復合賦值的操作是單個評估

這是否意味着,表達式:

int a = 1, b = 10;
int c = (a+=1) + (b+=1);

if ( c == 10+1+1+1 ) {
    printf("this is guaranteed");
} else {
    printf("not guaranteed"); 
}

將始終評估為c==23

表達方式

int c = (a+=1) + (b+=1);

(編輯:添加了缺少的括號,我認為這是你的意圖)

有以下子表達式

(1) a+=1
(2) b+=1
(3) (1)+(2)
(4) c = (3)

未指定評估(1)和(2)的順序,編譯器可以自由選擇它喜歡的任何順序。

在編譯器可以評估(3) 之前 ,必須評估(1)和(2)。

(3)必須在編譯器評估之前進行評估(4)。

現在,由於(1)和(2)的評估順序無關緊要,整體結果已明確定義,您的代碼將始終產生13並打印“這是現在的標准”。 請注意,這一直是這樣,這對於C ++ 11來說並不新鮮。

在您的示例中,編譯器應發出錯誤,因為加法運算符的優先級高於賦值運算符的優先級。 因此,首先計算1 + b,然后嘗試將1分配給表達式(1 + b),但(1 + b)不是左值。

這一直是有保證的,並且規則之前的順序(或前C ++ 11中的序列點規則)不需要確定這一點。 在C ++中,每個(子)表達式在生成的代碼中有兩個重要的影響:它有一個值(除非它是void類型),它可能有副作用。 排序的前/序列點規則影響何時保證發生副作用; 它們對子表達式的值沒有影響。 在您的情況下,例如, (a += 1)是值a將具有分配之后,而不管當實際分配發生的。

在C ++ 11,實際的修改a保證的修改之前進行c ; 在預C ++ 11中,沒有關於訂單的保證。 然而,在這種情況下,合規程序無法看到這種差異,因此無關緊要。 (在c = (c += 1)情況下這很重要,這在C ++ 11之前是未定義的行為。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM