Sequenced-before是在 C 標準中定義的
如果 A 在 B 之前排序,則 A 的評估將在 B 的評估開始之前完成
還有一長串關于 A 何時在 B 之前排序的規則。
但是,從這個串列中,我發現一個完整的運算式在下一個完整的運算式之前排序。由于整個運算式陳述句是一個完整的運算式,所以在下面的代碼中,3/4/5 是完整的運算式,而 1/2 不是(它們是宣告陳述句)。
int main(){
int a = 1; // 1
int b = 2; // 2
a = 10; // 3
b = 20; // 4
printf("%d %d", a, b); // 5
}
那么,根據sequenced-before的定義,編譯器/CPU可以重新排序3/4嗎?
我有兩個答案:
不,他們不能
這是因為 3 在 4 之前排序,所以 3 必須在 4 之前執行。
是的,罐頭
根據as-if 規則,C 允許任何和所有不改變程式可觀察行為的代碼轉換。由于 3 和 4 的順序無關緊要,因此編譯器/CPU 完全有理由根據 as-if 規則重新排序。
似乎我在這里得到了一個矛盾。
更新
怎么樣
int main(){
int a = 1; // 1
int b = 2; // 2
a = random_int(); // 3
b = random_int(); // 4
printf("%d %d", a, b); // 5
}
uj5u.com熱心網友回復:
如果您無法觀察到重新排序,編譯器只能重新排序 3 和 4。
這是一個(可以說)這樣做的例子
生成的目標代碼在 10 之前注冊 20
.LC0:
.string "%d %d"
main:
sub rsp, 8
mov edx, 20
mov esi, 10
xor eax, eax
mov edi, OFFSET FLAT:.LC0
call printf
xor eax, eax
add rsp, 8
ret
另一種解釋是,這不是重新排序,那些運算式已經消失。請注意如何沒有提及1或2不再提及。
uj5u.com熱心網友回復:
您不必擔心重新排序,至少只要您的程式是單執行緒的。
seqenced-before 關系決定了您將看到的行為。
然后編譯器可以重新排序它想要的任何東西,只要可觀察的行為符合前序。
怎么樣
random_int()?
不管你呼叫什么函式,重新排序都不會影響可觀察的行為。
由于整個運算式陳述句是一個完整的運算式,所以在下面的代碼中,3/4/5 是完整的運算式,而 1/2 不是(它們是宣告陳述句)。
如果我們正在分裂頭發,它們都不是完整的表情。:P
在
int a = 1; // 1
int b = 2; // 2
a = 10; // 3
b = 20; // 4
printf("%d %d", a, b); // 5
完整運算式是:1, 2(初始值設定項), a = 10, b = 20, printf("%d %d", a, b).
a = 10;(with ;) 是運算式陳述句,但不是運算式。如果洗掉;,它會變成一個完整的運算式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/405190.html
標籤:
上一篇:錯誤:呼叫RunInstances操作時發生錯誤(InvalidKeyPair.NotFound):密鑰對“key-oregon.pem”不存在
