チェインされた静的関数とメンバー関数で引数の評価順序に違いがあるのはなぜでしょうか。この質問の回答から、このような連鎖関数呼び出し間の引数評価順序が指定されていないことがわかります。たとえば、次のスニペットを見てください。
#include <iostream>
class test {
public:
static test& chain_s(test& t, int i) {
std::cout << i << " ";
return t;
}
test& chain(test& t, int i) {
std::cout << i << " ";
return *this;
}
};
int main(int, char**) {
int x = 2;
test t;
t.chain(t,++x).chain(t,++x).chain(t,++x);
x = 2; std::cout << std::endl;
t.chain_s(t,++x).chain_s(t,++x).chain_s(t,++x);
return 0;
}
GCC 4.6.2 および CL 15.00.30729.01 (MSVC 9) の場合、結果の出力は私のためのものです
5 5 5
3 4 5
しかし、仕様に何らかの理由があるのか 、それとも静的関数が左から右に(引数とともに)評価され、非静的関数の場合はすべての引数が最初に評価されるのか(right-私が他のテストで見たものから左へ)。
私がこれを尋ねている理由は、C で (構造体と関数ポインターを使用して) 同様の動作を取得しようとして失敗したときに、この動作の違いに最初に気付いたからです。これは、メンバー関数の GCC と MSVC の両方で実装された最適化であると強く疑っていますが、ここの誰かがこれについてもう少し詳しく説明してくれることを願っています。
編集:
奇妙に感じる重要な情報を 1 つ言及するのを忘れていました: GCC は、チェーンされた非静的関数の未指定の動作についてのみ警告しますが、静的関数については警告しません:
a.cpp: In function 'int main(int, char**)':
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point]
GCC はそのような警告を提供する義務はないので、2 番目の式を見逃す可能性がありますが、これが何か興味深いことが起こっていると私に思わせます。