I've been reading C++ Primer for some time now. Every time I encounter a problem I manage to solve it myself. This time I don't. This book claims that the following code is undefined, but I can't understand why?
Quote from the book
"For operators that do not specify evaluation order, it is an error for an expression to refer to and change the same object. Expressions that do so have undefined behavior. As a simple example, the << operator makes no guarantees about when or how its operands are evaluated. As a result, the following output expression is undefined:
1 2
int i = 0;
cout << i << " " << ++i << endl; // undefined
Because this program is undefined, we cannot draw any conclusions about how it might behave. The compiler might evaluate ++i before evaluating i, in which case the output will be 1 1. Or the compiler might evaluate i first, in which case the output will be 0 1. Or the compiler might do something else entirely. Because this expression has undefined behavior, the program is in error, regardless of what code the compiler generates".
After testing several times the results were the same.
I seriously can't understand why this expression should be undefined.
Well this example uses the pre-increment operator. We do not know if the compiler will increment i by 1 first, or display i first. My compiler leaves output as 1 1, but not all compilers are guaranteed that same output, thus its undefined.
I seriously can't understand why this expression should be undefined.
It's undefined by definition, as explained in the quote. Similar to reading past the end of an array - in C++, the behavior of the program that attempts to do so is undefined.
After testing several times the results were the same.
It doesn't matter what results you got on your particular version of your particular compiler. The program has an error and even the same compiler doesn't have to work the same way next time.
Those are four distinct statements (or "full-expressions").
cout << i << " " << ++i << endl; // undefined
That is one single statement (or "full-expression").
Remember that all value fetching, calculations, and side-effects like assignment must be done by the time we finish evaluating each full-expression.
But inside an expression, there is no such requirement. Hence, we cannot say what the value of i is: is it the value before++i or after? Since those two things are "unsequenced" we cannot say -- and the expression is undefined.