16

I'm not sure whether statement below is well defined by standard C or not

*p1++ += 2;

or other similar statement:

*E1++ <operator>= E2

From standard C about post-increment:

The result of the postfix ++ operator is the value of the operand. After the result is obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate type is added to it.) See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point.

And about coumpund-assignment:

A compound assignment of the form E1 op= E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once.

dragon135
  • 1,366
  • 8
  • 19
  • Well, what exactly triggered your suspicion that it might be undefined? To me, for one example, everything looks fine, which makes it difficult to me to even start answering the question: I don't know what to focus on. – AnT stands with Russia Oct 17 '14 at 02:52
  • 2
    Dont write codes in project like this, except you research on it. – wshcdr Oct 17 '14 at 03:14
  • 9
    Writing this kind of illegible code just to stuff more code on one line is bad programming. :) – Almo Oct 17 '14 at 04:24
  • 1
    Who cares. If this code is any real program it would be immediately removed. In reality it should never pass a code review and get into the code base. So whether it does what the original developer expects is irrelevant as the next developer to see will **not** immediately understand it and thus refactor it out of the code base. – Martin York Oct 17 '14 at 08:31
  • 1
    The question is relevant, if there was a wider context e.g. "my program behaves differently when compiled with GCC and Visual C++. I came across this line in it - could this be the problem?" – user23614 Oct 17 '14 at 08:49

2 Answers2

23

Let's rewrite slightly to make it more clear:

(*p1++) += 2

So the old value of p1 will be dereferenced, and 2 will be added to its referent. And p1 will be incremented after it is dereferenced (or at least, after its old value is loaded and waiting to be dereferenced). There's no problem here: none of the pieces is used more than once.

That being said, you should consider rewriting the code for clarity:

*p1 += 2;
++p1;
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 9
    "then" isn't quite right, the side effect of += could happen before or after the side effect of ++. They key is that they are on different scalar objects. – Cubbi Oct 17 '14 at 03:06
3

Postfix increment operator (++) gives the value of operand, i.e. it gives an r-value. The r-value implies that it be used on the left of the assignment operator (=) as an operand.

int i = 0;
i++ = 0   // [Error] lvalue required as left operand of assignment  

In case of

*p1++ += 2;  

postfix ++ is not applied on *p1, but it is applied to pointer p1++. This is because postfix ++ has higher precedence than that of derereference operator *. So, compiler will parse the above statement as

*(p1++) += 2;

and this says that:

  • *p1 must be evaluated (to produce a variable) before adding 2 and assigning the result to it.
  • Result to be stored to *p1 must be evaluated before the increment to p1.
  • Once *p1 is evaluated, p1 can be increment at any time.
haccks
  • 104,019
  • 25
  • 176
  • 264