"x = ++x" is it really undefined?
Asked Answered
V

6

14

I am using Coverity Prevent on a project to find errors.

It reports an error for this expression (The variable names are of course changed):

x=
   (a>= b) ?
   ++x: 0;

The message is:

EVALUATION_ORDER defect: In "x=(a>= b) ? ++x: 0;", "x" is written in "x" (the assignment LHS) and written in "(a>= b) ? ++x: 0;" but the order in which the side effects take place is undefined because there is no intervening sequence point. END OF MESSAGE

While I can understand that "x = x++" is undefined, this one is a bit harder for me. Is this one a false positive or not?

Veliger answered 1/9, 2010 at 14:49 Comment(3)
The title of your question is confusing. You say that you understand that x = x++ is undefined. Yet, your question title seems to ask whether x = ++x is defined. Does that mean that you don't understand that x = ++x is undefined? Or is your question actually about the case with conditional ?: operator?Hl
Sorry for the confusion. I did understand that x = x++ is undefined, but didn't (past tense) understand why (and if) x = ++x was undefined. I didn't believe that ?: was the main rot of the problem, therefore I omitted it (unfortunatly without telling why). But to preserve the integrity of the Coverity message, I kept it in the Coverity message. I agree that that made my question a litte bit confusing.Veliger
Is this also undefined for JAVA? Because I see here careercup.com/question?id=13543663 and the most upvoted ans suggests that it will give a defined output.Mort
H
30

Conditional operator ?: has a sequence point between evaluation of the condition (first operand) and evaluation of second or third operand, but it has no dedicated sequence point after the evaluation of second or third operand. Which means that two modifications of x in this example are potentially conflicting (not separated by a sequence point). So, Coverity Prevent is right.

Your statement in that regard is virtually equivalent to

a >= b ? x = ++x : x = 0;

with the same problem as in x = ++x.

Now, the title of your question seems to suggest that you don't know whether x = ++x is undefined. It is indeed undefined. It is undefined for the very same reason x = x++ is undefined. In short, if the same object is modified more than once between a pair of adjacent sequence points, the behavior is undefined. In this case x is modified by assignment and by ++ an there's no sequence point to "isolate" these modifications from each other. So, the behavior is undefined. There's absolutely no difference between ++x and x++ in this regard.

Hl answered 1/9, 2010 at 14:53 Comment(3)
+1: Am surprised why Comeau Online does not give error for either this case or the simple case of 'x = x++;'Petronius
@chubsdad: I don't remember Comeau Online ever catching such situations. GCC is known to issue warnings in cases like that, but it doesn't complain about the ?: case.Hl
Is this also undefined for JAVA? Because I see here careercup.com/question?id=13543663 and the most upvoted ans suggests that it will give a defined output.Mort
B
12

Regardless of the accuracy of the message, replacing the code in question by x= (a>= b) ? x+1: 0; achieves the same end without any confusion. If the tool is confused then maybe the next person to look at this code will be too.

This does assume that x does not have an overloaded increment operator with side-effects that you rely on here.

Blanchette answered 1/9, 2010 at 14:53 Comment(5)
And please, out of the goodness of your heart to other developers, please don't call things x, a and b.Haymaker
@Dominic: the question clearly states that the names where changed from the original names.Tawnytawnya
@Joachim - ah, missed that, phew!Haymaker
If it has an overloaded increment operator with side effects you rely on, someone deserves to be shot! :-pZenaidazenana
If it has an overloaded increment operator, @Steven, then there's no longer any issue of undefined behavior. The increment operator will be fully evaluated before the assignment operator begins.Defalcate
C
8

The statement x = ++x; writes to the variable x twice before hitting the sequence point and hence the behavior is undefined.

Custos answered 1/9, 2010 at 14:53 Comment(0)
L
3

It is hard to imagine a compiler producing code for "x = ++x;" which would in fact not work the same as "++x". If x is not volatile, however, it would be legal for a compiler to process the statement "y = ++x;" as

  y=x+1;
  x=x+1;

The statement "x = ++x;" would thus become

  x=x+1;
  x=x+1;

If having the destination of one an arithmetic assignment expression get used too quickly as a source operand for another would cause a pipeline delay, the former optimization might be reasonable. Obviously disastrous if the incremented and assigned variable are one and the same.

If variable 'x' is volatile, I can't think of any code sequence where a compiler that wasn't deliberately trying to be mean could legitimately regard "x = x++;" as having any effect other than reading all parts of 'x' exactly once and writing the same correct value to all parts of 'x' exactly twice.

Loeb answered 1/9, 2010 at 16:30 Comment(0)
C
0

I suppose that logically, if you write either "x=++x" or "x=x++", either way you would expect the end result to be that x is one more than it started as. But make it just a shade more complicated. What if you wrote "x=x+(++x)" ? Is this the same as "x=x+(x+1)" ? Or do we add one first and then add x to itself, i.e. "x=(x+1)+(x+1)"? What if we wrote "x=(x--)+(x++)" ?

Even if you could write a language spec that gave unambiguous meaning to these sort of constructs, and could then implement it cleanly, why would you want to? Putting a unary increment in an assignment to the same variable just doesn't make sense, and even if we forced sense out of it, it provides no useful functionality. Like, I'm sure we could write a compliler that would take an expression like "x+1=y-1" and figure out that that really means "x=y-2", but why bother? There's no gain.

Even if we wrote compilers that did something predictable with "x=x++-++x", programmers would have to know and understand the rules. Without any obvious benefit, it would just add complexity to programs for no purpose.

Catchpole answered 1/9, 2010 at 17:5 Comment(0)
O
0

In order to understand this you need to have a basic understanding of sequence points. See this link: http://en.wikipedia.org/wiki/Sequence_point

For the = operator there is no sequence point, so there is no guarantee that the value of x will be modified before it is again assigned to x.

Ode answered 6/3, 2012 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.