I am curious why there is a difference in the argument evaluation order between chained static functions and member functions. From the answers at this question I can see it is unspecified what the argument evaluation order is between such chained function calls. Take for example the following snippet:
#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;
}
In the case of GCC 4.6.2 and CL 15.00.30729.01 (MSVC 9) the resulting output is for me
5 5 5
3 4 5
However, I was wondering if there is any reason in the specification or if it is otherwise known why the static function are evaluated left-to-right (with their arguments), and for the non-static function all the arguments first (right-to-left from what I've seen in other tests).
The reason I'm asking this is because I first noticed this difference in behavior when trying to get similar behavior in C (using a struct and a function pointer) and failed. I strongly suspect this is some optimization implemented both in GCC and MSVC for member functions, but I hope someone here can shed a little more light on this.
Edit:
I forgot to mention one crucial bit of information which strikes me as odd: GCC will only warn on unspecified behavior on the chained non-static function, but not the static functions:
a.cpp: In function 'int main(int, char**)':
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point]
GCC is not obligated to provide such warnings so it could miss the second expression, but this is what leads me to believe something interesting is going on.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…