@Grey Wolf: I know why you coded it that way, no worries. The poor construction is not yours, I know, hehe.
Results I got:
http://www.ideone.com/DQAsc: Same as Grey Wolf.
VS2008: The same as well, with no optimization, with speed optimization and with full optimization, both debug and release versions.
It clearly states the point Disch is making, no argue there.
I think, though, that such a thing wouldn't have existed in the first place. Why do compilers are free to implement the order of evaluation when the operators clearly have a precedence assigned (as well as the associativity)?
In the example of the webpage, I would have coded the compiler to read the expression and then start evaluating the bits of it according to operator precedence. In the example (x = x / ++x), I would have evaluated ++x first, then I would have evaluated x / ++x, and finally I would have made the assignment. There is no other interpretation possible from the operator precedence + associativity there.
If the expession were x = f() + g();, then I undestand that a compiler could evaluate either f() or g() first, but not really because the associativity of operator+ is defined: Left to right. Why would a compiler deviate from these clearly defined rules?? I don't get it. I understand that it probably happens, I just don't get why if operator precedence rules are quite clear.
but not really because the associativity of operator+ is defined: Left to right. Why would a compiler deviate from these clearly defined rules?? I don't get it. I understand that it probably happens, I just don't get why if operator precedence rules are quite clear.
I think you're misunderstanding what "left to right" means.
All "left to right associativity" means is that a + b + c will evaluate as (a + b) + c and not a + (b + c)
It makes no distinction as to which order a, b, or c are evaluated (if they are expressions that need evaluating, such as function calls).
In a + b + c, the only things that are guaranteed are:
- the left + will evaluate before the right +
- a and b will both be evaluated before the left +
- c will be evaluated before the right +
However this leaves some details open:
- is c evaluated before the left +?
- is a evaluated before b?
Those details are not defined by the standard, so the compiler can do it any way it wants.
Ahhhhhhhh, I see. Associativity is between instances of the same operator, and not the operands. I clearly see now that f() or g() could be evaluated first.
I also see that c in your example can be evaluated before.
Still, the expression x = x / ++x; should be correct, shouldn't it? The assignment operator has almost the lowest precedence, so no discussion it will be the last one there. That leaves us with 2 operators more. Between / and prefix ++, prefix ++ has the higher precedence. This means prefix ++ must be evaluated first and then operator/ is second. And that resolves the example, doesn't it? If not, please tell me what I'm missing here.
And to come back to the point of the thread: b->prev->next = b->prev = c;. In this expression I get now that the right hand operator= goes first, but without guarantees of which side is evaluated first. I don't see, however, how this could ever yield a different result: operator-> has much higher precedence, so b->prev is evaluated first before evaluating right hand operator= (regardless of whether it was evaluated before or after right hand operand 'c'). This messes up the expected result in the left hand operator=. I just can't make this work differently in my head even after applying the correction made by Disch.
BTW, thanks Disch for correcting my understanding of associativity.
Doh! My bad about expression x = x / ++x; It just hit me! Surely prefix ++ goes first, no doubt about it, but could the compiler had already evaluated left hand operand 'x'?? That's why it is undefined.
By bad there.
Second expression: b->prev->next = b->prev = c; stills stands, though.
EDIT: It doesn't stand anymore. I see now. It hit me equally hard now. Surely right hand operator= goes first, but maybe the compiler could have evaluated lefthand operand 'b->prev->next' of left hand operator= and have it there "ready" just waiting till after evaluation of right hand operator=.
Ok, so I think I'm slow. Thanks for your patience. OP: Did I mess up your head? If I did, I apologize. :-(
Associativity is between instances of the same operator
Associativity determines how operators of the same precedence are grouped in the absence of parentheses.
for example multiplication and division have the same precedence and they are Left-to-right associative. So, in x * y / z you can be assured that the multiplication is done first the the division.
Surely right hand operator= goes first, but maybe the compiler could have evaluated lefthand operand 'b->prev->next' of left hand operator= and have it there "ready" just waiting till after evaluation of right hand operator=.
It means that the expression is replaced by the thing that it refers to. X->Y is evaluated and replaced by a reference to Y. This may or may not be affected by changes later in the same statement, and it may be evaluated before or after other expressions in the statement.
evaluate: Find or calculate the value of. evaluate left operand: Calculate the value of left operand. Example: f() + b; In this example, the compiler needs to evaluate both left and right operands. It is obvious that the left operand is a function call. To know the value of the left operand, the function must be executed. The right hand side also needs evaluation, but if it is a variable of an intrinsic data type, its evaluation is trivial (evaluate b equals the value of b).
I'd like to thank everyone who contributed to the post. I am one of the authors of the textbook from which this code was extracted ("Data Structures and Algorithms in C++", 2nd Edition, Wiley 2011), and my error was the cause of all this confusion.
The original statement was supposed to read:
v->prev->next = u;
v->prev = u;
It was carelessly shortened to:
v->prev->next = v->prev = u;
We will be sure to correct this error in future printings of the book.