4

Let me present a example :

a = ++a;

The above statement is said to have undefined behaviors ( I already read the article on UB on SO)

but according precedence rule operator prefix ++ has higher precedence than assignment operator =

so a should be incremented first then assigned back to a. so every evaluation is known, so why it is UB ?

Mr.Anubis
  • 5,132
  • 6
  • 29
  • 44
  • Just for the fun of it, apparently in C++11 that statement seems to be perfectly defined, unlike `a = a++;` (http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points/4183735#4183735). It would be so much more fun to be able to yell "undefined behavior", but now one would have to be much more careful... – UncleBens Sep 21 '11 at 21:45
  • `++a` doesn't guarantee that `a` first will be set, then it's new value will be returned. Only that `a` will be set some time before the next sequence point and that `a + 1` will be returned. – potrzebie Oct 01 '13 at 01:08

5 Answers5

10

The important thing to understand here is that operators can produce values and can also have side effects.

For example ++a produces (evaluates to) a + 1, but it also has the side effect of incrementing a. The same goes for a = 5 (evaluates to 5, also sets the value of a to 5).

So what you have here is two side effects which change the value of a, both happening between sequence points (the visible semicolon and the end of the previous statement).

It does not matter that due to operator precedence the order in which the two operators are evaluated is well-defined, because the order in which their side effects are processed is still undefined.

Hence the UB.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
3

Precedence is a consequence of the grammar rules for parsing expressions. The fact that ++ has higher precedence than = only means that ++ binds to its operand "tighter" than =. In fact, in your example, there is only one way to parse the expression because of the order in which the operators appear. In an example such as a = b++ the grammar rules or precedence guarantee that this means the same as a = (b++) and not (a = b)++.

Precedence has very little to do with the order of evaluation of expression or the order in which the side-effects of expressions are applied. (Obviously, if an operator operates on another expression according to the grammar rules - or precedence - then the value of that expression has to be calculated before the operator can be applied but most independent sub-expressions can be calculated in any order and side-effects also processed in any order.)

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
1

why it is UB ?

Because it is an attempt to change the variable a two times before one sequence point:

  • ++a
  • operator=
BЈовић
  • 62,405
  • 41
  • 173
  • 273
1

Sequence point evaluation #6: At the end of an initializer; for example, after the evaluation of 5 in the declaration int a = 5;. from Wikipedia.

You're trying to change the same variable, a, twice. ++a changes it, and assignment (=) changes it. But the sequence point isn't complete until the end of the assignment. So, while it makes complete sense to us - it's not guaranteed by the standard to give the right behavior as the standard says not to change something more than once in a sequence point (to put it simply).

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
0

It's kind of subtle, but it could be interpreted as one of the following (and the compiler doesn't know which:

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

This is because of some ambiguity in the grammar.

nulvinge
  • 1,600
  • 8
  • 17
  • 1
    Although C++ is grammar is ambiguous in some places, this isn't one of them. The parsing of `a = ++a;` is completely unambiguous it's just that the behaviour is not defined. – CB Bailey Sep 21 '11 at 21:25
  • True, but what the semantics of the grammar is ambigous, hence undefined behavior. – nulvinge Sep 21 '11 at 21:35
  • I'm not sure exactly what you mean by "semantics of the grammar". The expression has explicitly undefined behavior, I don't believe there's any ambiguity. – CB Bailey Sep 21 '11 at 21:41
  • The semantics are ambiguous, thus they cannot be defined, and that is why it's called undefined behavior. If there where no ambiguity then it would be defined behavior. – nulvinge Sep 21 '11 at 21:49
  • I can't help thinking that we must be arguing at cross purposes; this may be because we don't agree on the definitions of some fundamental terms. – CB Bailey Sep 22 '11 at 07:52
  • Yes, and I gave you the explanation of the difference in terms. 'Ambiguous' literally means 'not clearly defined', which is a synonym to 'undefined'. Thus ambiguous behavior is undefined behavior. 'Semantics' literally means 'study of meaning', and the meaning of code is to do something, have some *behavior*. Thus 'ambiguous semantics' means exactly the same thing as 'undefined behavior'. – nulvinge Sep 22 '11 at 20:08
  • OK, that explains my confusion. I haven't ever come across anyone use the phrase "ambiguous semantics" as an alternative to "undefined behavior" before. I still thing that your original use of the phrase "some ambiguity in the grammar" is misleading, though. – CB Bailey Sep 22 '11 at 20:19
  • Yes, as I said I concurred with that it was misleading, because I meant the semantics. The documentation of the grammar describes the semantics too, hence the confusion. – nulvinge Sep 22 '11 at 20:27