preincrement and assignment

Started by
26 comments, last by MaulingMonkey 15 years ago
I simply stated one possible scenario of undefined behavior -- there are others, like the one you encountered. If I write
"hello"[1] = 'a';

and the computer does not crash, this doesn't mean that's what always happens.
Advertisement
I'm not saying that it's always 1. I am saying that since it was 1 at least once, then saying that it should be 2 is wrong.
Ignoring the fact that undefined behaviour means you could get any answer...
How could you expect it to be possible to get two when that would mean incrementing the value of i when it equals 1, but to get to one to begin with means i was incremented already, thus it involves two increments?
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
You cannot get 2, and here's why, despite the lack of a sequence point.

Lets assume the scenario you describe for yielding a result of 2.

Given that 'i' is an integer with an initial value of 0, we begin our equation 'i = ++i'. We first evaluate the expression '++i' which means that the 'i' on both sides of the equation (which are, of course, one in the same) is now equal to 1. We've not yet gotten to the assignment, so it doesn't come into play just yet, but the '++' has been evaluated and eliminated from the equation, leaving us with 'i = i'. Since the value stored in 'i' is known to be '1', we can see that this equation reads as "store the value of 1 into the location i."

This is a logical explanation assuming what we already know: that the assignment is entirely redundant -- and here we've proven why.

I think the mistake you are making, is that you've confused the assignment operation taking place after the pre-increment, as repeating the increment on the new value, but that is not the case.

throw table_exception("(? ???)? ? ???");

Would a statement like this, be considered undefined as well ?

i = (i = i + 1);

To my mind the fact that there is no sequence point does not mean that the order of evaluation is not clearly indicated by the expression. Delaying the side-effect past a sequence point ( , or ;) by using a post increment in conjunction with an assignment both on the same cell is going to be iffy. I am not up to speed with the detail of the standard however so it is only an intuition.
I think neither has undefined behavior, assuming it's C++.
Even with i++ instead of ++i, it would be defined.
No, it's undefined behavior. From ISO/IEC 14882, section 5, paragraph 4:
Quote:Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.
Sorry, and thanks for the standard quote.
My compiler is even issuing a warning for this code.
* moves to For Beginners *
I don't believe this is undefined behavior, and if someone here could prove it, I would be shocked.

While what's been stated about sequence points is correct, that applies to situations such as x = ++i. This code is finding the address somewhere in the array x, and storing the result of the right side at that address. Because of this, depending on whether the left or right side is evaluated first changes the result.

In the case brought up here, that isn't as issue. Evaluating the left side will result in the same value regardless, so it boils down to whether the assignment can ever occur before the increment, and it can't. In this case, the behavior is well defined.
-- gekko
Quote:Original post by gekko
I don't believe this is undefined behavior, and if someone here could prove it, I would be shocked.

While what's been stated about sequence points is correct, that applies to situations such as x = ++i. This code is finding the address somewhere in the array x, and storing the result of the right side at that address. Because of this, depending on whether the left or right side is evaluated first changes the result.

No, that's just unspecified behavior when you don't know which one is executed first -- which applies to iterators and the like, but for plain types like int, SiCrane cited line and verse of the C++ standard which says why this is outright undefined behavior. I'm not sure how much more proven you can get beyond "This is exactly what the C++ standard says".

"shall have its stored value modified at most once" is violated by assigning to i with operator and incrementing i with ++i between sequence points. This doesn't apply to your example -- it only modifies i once with ++i (but it's still UB as that violates the other condition: "Furthermore, the prior value shall be accessed only to determine the value to be stored" -- the i in x is not read to determine the value to be stored.)

If you wish to argue against this, I'd suggest giving an example that violates the first bit -- "shall have its stored value modified at most once" -- and thus falling victim to UB, and then explaining what you feel makes that example different from i = ++i, which you're believing to not be UB.

This topic is closed to new replies.

Advertisement