Calling function twice in one printing statement

Why is the output "21", but not "12"?

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

int& add(int &value)
{
    ++value;
    return value;
}

int main()
{
    int result = 0;
    std::cout << add(result) << add(result);
}
Because order of function paramerer evaluaton is unspecified and modifying one value twice between sequence points is undefined behavior.

In your case std::cout << add(result) << add(result); is calculated first.
Then it transformed into std::cout << add(result) << 1;std::cout << 2 << 1;

Your code might output "11" and this will be completely valid because of undefined behavior of your code.
Last edited on
So is it true that I should not do this but rather I should use two printing statements?
Either:
1
2
std::cout << add(result);
std::cout << add(result);

or
1
2
int old = add(result);
std::cout << old << add(result);
> I should use two printing statements?

This would suffice:
1
2
const int first = add(result) ;
std::cout << first << add(result);

I think using two printing statements is easier.

I am reading a related question on Stack Overflow about Undefined Behavior and Sequence Points. I post it here in case someone has a similar problem.
http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points
Last edited on
Just to note: term Sequence Point is dropped in C++11. It uses sequenced-before now. It is mostly the same. You can read about it here: http://en.cppreference.com/w/cpp/language/eval_order

EDIT: I have read your link. It is discussed there too.
Last edited on
Thanks for your reminder. I will also read yours.
To be fair, two function calls to add() are, using C++11 wording, "indeterminately sequenced" (C++98 similar), so the output can only be 12 or 21. The behavior is not undefined, merely unspecified which of the two possibilities take place.
Last edited on
Oh, yes: the program must behave as if the CPU instructions that constitute different function calls were not interleaved, even if the functions were inlined

However I do not see anything preventing "22" to be outputted:
calculate right hand side function and store variable in temporary variable of return type of the function (store reference to result)
do the same for left function.
Pass arguments (copy valye references are pointing at).
@MiiNiPaa you are right, I overlooked the fact that the function here returns a reference.

You can certainly have the case where both functions are complete (result == 2) before any of operator<<'s int parameters are initialized from their arguments, so 22 is another allowed result.
Last edited on
Topic archived. No new replies allowed.