0

"C++ Primer" (5th edition) on page 148 defines the postfix increment operator: "The postfix operator returns a copy of the object's original value as an rvalue." This made sense to me. However, on page 149, it brings the following code as an example of undefined behavior:

while (beg != s.end() && !isspace(*beg))
    *beg = toupper(*beg++);

It proceeds to explain that, if the right side of the assignment is evaluated before the left side, then the compiler would evaluate the above expression as:

*(beg+1) = toupper(*beg)

To me this contradicts the above definition of the postfix increment operator. Namely, = is just an operator, so the whole line *beg = toupper(*beg++) is an expression, so that the effects of incremented value of beg should be held and not take any effect before the expression is fully evaluated. So, what is the precise definition of when the postfix increment takes effect? Also, does placing parentheses in the expression affect when this happens?


A similar question appeared at: Does postfix increment perform increment not on returned value?. One of the comments there cited the following discussion about sequence points: Undefined behavior and sequence points. However, I believe that there should be a short and clear definition: when does the postfix increment take effect? Without such a definition, I would be afraid to use the postfix form in any expression that's more complicated than the standard *p++ with no other uses of p in the expression.

Community
  • 1
  • 1
AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68
  • Sequence point. The linked question is the answer. Unless you can give a reason why the answers of that question can't explain this, this is a duplicate, in my opinion. – Yu Hao Jul 01 '15 at 11:34
  • 1
    That answer is long. It does not qualify as a short and precise definition. If that is the best answer, then I would advise myself: just don't use `a++` if you have another `a` in the same expression -- it's too much headache. But I hope that, may be, that long discussion can be distilled to a clear rule of thumb. – AlwaysLearning Jul 01 '15 at 11:38
  • That answer is as precise as I could imagine. If you want a more precise definition, look up the C++ standard. It's longer than most answers in this site, true, but that's probably because this problem is complecated. – Yu Hao Jul 01 '15 at 11:42
  • 4
    @Meir Well, that is a good advice and a rule of thumb. It's best not to have the variable you perform pre-/post- operator more than once, unless you are sure where sequence points are, and what are side effects. There is not simpler rule. – luk32 Jul 01 '15 at 11:48
  • I'm sorry but I don't think *That answer is long* is enough to make this question not the same as the duplicate. – Yu Hao Jul 01 '15 at 12:00

2 Answers2

0

As the second link you posted states out, this is a sequence point. So, the problem with this:

*beg = toupper(*beg++);

is that you do not know which part is going to be evaluated first (notice the * operator). If you are not convinced, read this answer.

You understand well the postfix concept, but you tangled up in a sequence point.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

Here increment takes place before assignment by toupper so the proccess is: *beg++; then *beg=toupper(*beg-1); I have written *beg-1 because *beg value has increased by one, but it takes previous value.

Madhu Kumar Dadi
  • 695
  • 8
  • 25