I\'ll skip the headers
class X {
int i;
static int j;
public:
X(int ii = 1) : i(ii) {
j = i;
}
static int incr() {
return ++
§ 1.9.13
Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. —end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. —end note ]
In other words, the order the functions are called is Undefined. That doesn't mean "we don't know", it doesn't mean "you can't work it out" - it means that it is defined as having no definition; the compiler and cpu are free to complete them in any order.
Consider the following:
int a[3];
void f1() { a[0] = 1; }
void f2() { a[1] = 2; }
void f3() { a[2] = 3; }
int main() {
f1(), f2(), f3();
}
Basically the language asserts no requirement for ordering on a statement like
std::cout << f1() << f2() << f3();
Your code has no sequence points (http://en.wikipedia.org/wiki/Sequence_point) between the function calls; you could figure out the order your compiler generates, but it might behave differently on a different CPU or a different optimization level.
If you have mutable function calls like that, you'll need to manually hoist or add breaks:
std::cout << f1();
std::cout << f2();
std::cout << f3();
or
auto a1 = f1();
auto a2 = f2();
auto a3 = f3();
std::cout << a1 << a2 << a3;
This statement
cout << x.f() << xp->f() << X::f();
can be rewritten like
cout.operator <<( x.f() ).operator <<( xp->f() ).operator <<( X::f() );
The order of evaluations of expressions used as arguments in this statement is unspecified. So the compiler can evaluates them for example from left to right or from right to left. Thus using different compilers you can get different results.:)
To get a deterministic result you should rewrite statement
cout << x.f() << xp->f() << X::f();
for example like
cout << x.f();
cout << xp->f();
coit << X::f();
The stream operator is simply an operator. C++ allows operators to be defined a multitude of ways. What you're seeing is the << operator for strings. What you're doing is the same thing as:
cout << "word1" << "word2" << "word3";
The expect output for that is:
"word1word2word3"
However, the evaluation order is determined by the implementation of the << operator. Usually the above is equivalent to:
(((cout << "word1") << "word2") << "word3");
Replace the strings with functions instead and you see the first one evaluated is actually "word3". This is not strictly the case, just what you'll usually see.
(((cout << func1()) << func2()) << func3());
Evaluation order would be func3, func2, func1, with print order the return of func1, func2, func3.