Order of assignment vs order of initialization

Operator associativity (i.e. right-to-left) is unrelated to evaluation order.* The evaluation order of the operands is unspecified.


* Except in a few cases, namely &&, || and ,.

The full expression

foo1() = foo2() = foo3() = 7

can be abstracted with the following tree:

     =
   /   \
foo1()   = 
       /   \
    foo2()   =
           /   \
        foo3()   7

The leaves of that tree can be evaluated in any order. Your compiler is free to choose. Only for calling the assignment operator the expressions hanging on them must be evaluated first. In your case the leaves get evaluated in the order foo1(), foo2() and then foo3().

The right to left associativity of = is only seen in the shape of the tree, but not in the order of evaluation. The tree for

std::cout << foo1() << foo2() << foo3()

looks like

                   << 
                 /    \
              <<      foo3()
            /    \
         <<      foo2()
       /    \
std::cout   foo1()

Again the foo functions may be evaluated in any order, but the order of evaluations of the operator<<() is well-defined. There is an interesting post about sequence points which describes the topics very well.