From Prasoon’s answer to question regarding “Undefined Behavior and Sequence Points”, I do not understand what the following means
.. the prior value shall be accessed only to determine the value to be stored.
As examples, the following are cited to possess Undefined Behaviour in C++:
a[i] = i++;int x = i + i++;
Despite the explanations given there, I do not understand this part (I think I correctly understand the rest of the answer).
I do not understand what is wrong with the above code samples. I think these have well defined steps for the compiler as below.
a[i] = i++;
a[i] = i;i = i + 1;
int x = i + i++ ;
x = i + i;i = i + 1;
What am I missing? What does ‘prior value shall be accessed only to determine the value to be stored’ mean?
See also this question and my answer to it. I’m not going to vote to close this as a duplicate because you’re asking about C++ rather than C, but I believe the issue is the same in both languages.
This does seem like an odd requirement; why should the standard care why a value is accessed? It makes sense when you realize that if the prior value is read to determine the value to be stored in the same object, that implicitly imposes an ordering on the two operations, so the read has to happen before the write. Because of that ordering, the two accesses to the same object (one read and one write) are safe. The compiler cannot rearrange (optimize) the code in a way that causes them to interfere with each other.
On the other hand, in an expression like
there are three accesses to
i: a read on the left hand side to determine which element ofais to be modified, a read on the right hand side to determine the value to be incremented, and a write that stores the incremented value back ini. The read and write on the RHS are ok (i++by itself is safe), but there’s no defined ordering between the read on the LHS and the write on the RHS. So the compiler is free to rearrange the code in ways that change the relationship between those read and write operations, and the standard figuratively throws up its hands and leaves the behavior undefined, saying nothing about the possible consequences.Both C11 and C++11 change the wording in this area, making some ordering requirements explicit. The “prior value” wording is no longer there. Quoting from a draft of the C++11 standard, 1.9p15: