簡體   English   中英

C語言評估順序

[英]Evaluation Order of C Language

  1. x+=x*=x是未定義的行為嗎?
  2. 任何人都可以按評估順序解釋此規則嗎? 什么是“單一評價”? “單一評價”的反義詞是什么?

    14) 對於不確定順序的 function 調用,復合賦值運算符的操作,以及遞增和遞減運算符的前綴和后綴 forms 都是單次評估。

x+=x*=x具有未定義的行為,因為x在序列點之間被分配了兩次。


C11、C17中14)對應的文字說

形式為 E1 op= E2 的復合賦值等價於簡單賦值表達式 E1 = E1 op (E2),除了左值 E1 僅計算一次,並且對於不確定順序的 function 調用,a 的操作復合賦值是一個單一的評估。

我相信這意味着

int x = 0;

int foo(void) {
    x = 5;
    return x;
}

int main(void) {
    int y = foo() + (x += 2); 
}

將具有以下一行為

int main(void) {
    int _tmp = x += 2;
    int y = foo() + _tmp; 
}

或者

int main(void) {
    int _tmp = foo();
    int y = _tmp + (x += 2); 
}

並且不能拆分為例如

int main(void) {
    int _tmp = x;
    int _tmp2 = foo();
    x = _tmp + 2;
    int y = _tmp2 + x; 
}

注意這個保證是C11中新增的,在C89、C99中是不存在的。

1) 是的。

C17 6.5.16 賦值運算符,§3

操作數的評估是無序的。

由於 C17 6.5 §2,這使它成為 UB

如果標量 object 上的副作用相對於同一標量 object 上的不同副作用或使用相同標量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z 的值的值計算未排序,則行為未定義

每個任務都是一個副作用。 C99 有相同的規則,但更容易理解:

C99 6.5 §2

在前一個和下一個序列點之間,object 的存儲值最多只能通過表達式的評估修改一次。 此外,應僅讀取先驗值以確定要存儲的值。


2) 所有帶有 C11 序列變化的文本閱讀起來相當混亂。 他們使用沒有在任何地方正式定義的術語,例如“單一評估”。

規范性文本為 C17 6.5.15.2 §3

形式為 E1 op= E2 的復合賦值等價於簡單賦值表達式 E1 = E1 op (E2),除了左值 E1 僅計算一次,並且對於不確定順序的 function 調用,a 的操作復合賦值是一個單一的評估。

我想這只是意味着像int x;這樣的操作。 ... x += 1應該產生如下機器代碼:

  • 將 1 存儲在寄存器中
  • 加 x 注冊
  • 將寄存器寫入 x

否則,假設某些東西在更新x的操作之間獲得序列。 但是復合賦值無論如何都不是原子的,所以我不太明白這里的標准是什么。

暫無
暫無

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

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