Sequence Points vs Operator Precedence

Possible Duplicate:
Unsequenced value computations (aka sequence points)
Undefined Behavior and Sequence Points
Operator Precedence vs Order of Evaluation

I'm still trying to wrap my head around how the following expression results in undefined behavior:

a = a++;

Upon searching SO about this, I found the following question:

Difference between sequence points and operator precedence? 0_o

I read through all the answers but I still am having difficulty with the details. One of the answers describes the behavior of my above code example as ambiguous, in terms of how a is modified. For example, it could come down to either of these:

a=(a+1);a++;
a++;a=a;

What exactly makes a 's modification ambiguous? Does this have to do with CPU instructions on different platforms, and how the optimizer can take advantage of the undefined behavior? In other words, it seems undefined because of the generated assembler?

I don't see a reason for the compiler to use a=(a+1);a++; , it just looks quirky and doesn't make much sense. What would possess the compiler to make it behave this way?

EDIT:

Just to be clear, I do understand what is happening, I just don't understand how it can be undefined when there are rules on operator precedence (which essentially defines the order of evaluation of the expression). Assignment happens last in this case, so a++ needs to be evaluated first, to determine the value to assign to a . So what I expect is that a is modified first, during the post-fix increment, but then yields a value to assign back to a (second modification). But the rules for operator precedence seem to make the behavior very clear to me, I fail to find where there is any "wiggle-room" for it to have undefined behavior.


The first answer in the question you linked to explains exactly what's going on. I'll try to rephrase it to make it more clear.

Operator precedence defines the order of the computation of values via expressions. The result of the expression (a++) is well understood.

However , the modification of the variable a is not part of the expression. Yes, really. This is the part you're having trouble understanding, but that's simply how C and C++ define it.

Expressions result in values, but some expressions can have side effects. The expression a = 1 has a value of 1 , but it also has the side effect of setting the variable a to 1 . As far as how C and C++ define things, these are two different steps. Similarly, a++ has a value and a side-effect.

Sequence points define when side effects are visible to expressions that are evaluated after those sequence points. Operator precedence has nothing to do with sequence points. That's just how C/C++ defines things.


This is probably too simplistic an explanation, but I think it is because there's no way to resolve when the code is "done" with "a". Is it done after the increment, or the assignment? The resolution ends up being circular. Assignment after the increment changes the semantics of when the incremented value is applied. That is, the code isn't done with "a" until "a" gets incremented, but a doesn't get incremented until the after the assignment is made. It's almost a language version of a deadlock.

As I said, I'm sure that's not a great "academic" explanation, but that's how I bottle it up between my own ears. Hope that's somehow helpful.


The precedence rules specify the order in which expressions are evaluated, but side effects do not have to happen during evaluation. They can be happen at any time before the next sequence point.

In this case, the side effect of the increment is sequenced neither before nor after the assignment, so the expression has undefined behaviour.

链接地址: http://www.djcxy.com/p/73232.html

上一篇: 扭曲的C ++代码

下一篇: 序列点与运算符优先级