[英]C++ Order of Evaluation
我想弄清楚C ++ 11規范中是否有任何內容。 以下代碼的預期行為( 此處為GitHub鏈接 ):
struct Scalar {
int data;
Scalar(int x) : data(x) {}
int get() {
return data;
}
Scalar &square() {
scale(data);
return *this;
}
void scale(int rhs) {
data *= rhs;
}
};
int main() {
Scalar v(3);
v.square().scale(v.get());
return v.data;
}
這主要是因為發現這在g++
和clang++
之間做了不同的事情:
$ g++ --version
g++ (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang++ --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ g++ -std=c++11 order_of_ops.cpp -o a.out && ./a.out; echo $?
27
$ clang++ -std=c++11 order_of_ops.cpp -o a.out && ./a.out; echo $?
81
答案似乎應該是在n3242的§5.2.2和§5.2.5中,但是我無法追蹤具體的東西。
如果我正確讀取了內容,則代碼的行為未指定。 N3337 for C ++ 11引用:
§1.9[intro.execution] / 15
除非另有說明,否則對單個運算符的操作數和單個表達式的子表達式的評估是不確定的。 [...]如果標量對象的副作用相對於同一標量對象的另一個副作用或使用相同標量對象的值的計算值未被排序,則行為未定義。
但接下來是
調用函數(包括其他函數調用)中的每個評估(在執行被調用函數的主體之前或之后沒有特別排序)對於被調用函數的執行是不確定地排序的。 9
9)換句話說,函數執行不會相互交錯。
和
§5.2.2[expr.call] / 8
[ 注意:后綴表達式和參數表達式的評估都是相對於彼此的無法排序的。 在輸入函數之前,對參數表達式評估的所有副作用進行排序(參見1.9)。 - 尾注 ]
因此,您對Scalar::data
修改和無關讀取是不確定的。
話雖這么說,它可能會改變並在C ++ 1z中得到很好的定義:
N4606§5.2.2[expr.call] / 5
后綴 表達式在表達式列表中的每個表達式和任何默認參數之前進行排序。 參數的初始化(包括每個相關的值計算和副作用)相對於任何其他參數的初始化是不確定的。
因此,在C ++ 1z中,你的v.data
應該等於81(如果我正確讀取的話)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.