You are correct, and the interviewer shows a frighteningly common lack of understanding about the language and its rules.
Those two lines are strictly equivalent, iff every operator<<
called for the first line is always a free function (The standard says they are).
As you rightly thought, the ordering between the function-calls, except where ones arguments are the return-value of another, are indeterminately sequenced (before or after, but unspecified which):
1.9 Program execution [intro.execution]
[...]
15 [...]
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ] Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.9 Several contexts in C++ cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit. [ Example: Evaluation of a new expression invokes one or more allocation and constructor functions; see 5.3.4. For another example,
invocation of a conversion function (12.3.2) can arise in contexts in which no function call syntax appears. —end example ] The sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
Naming all the parts:
cout << one() // a) execute one() ("one\n")
// b) output the return-value ("1")
<< '\n' // c) output newline ("\n")
<< two() // d) execute two() ("two\n")
// e) output the return-value ("2")
<< '\n'; // f) output newline ("\n")
Ordering constraints:
a < b < c < e < f
d < e < f
Or a different representation:
a < b < c <
< e < f
d <
Thus, all valid full orders:
abcdef "one\n1\ntwo\n2\n"
abdcef "one\n1two\n\n2\n"
adbcef "one\ntwo\n1\n2\n"
dabcef "two\none\n1\n2\n"