Mav3rick
Mav3rick

Reputation: 774

Is this well defined code?

I'm still slightly confused after reading this topic. Is the following C++ expression *d++ = ~(*d); well defined? Yes, I know compound expressions like this are ugly.. I didn't write it.

I see a slight difference in the generated assembly when I compare it to:

*d = ~(*d);
d++;

Assembly:

*d++ = ~(*d);
0x83384    LDR           R3,[R0 <d>,4]        <<diff
0x83388    ADD           R1 <c>, R1 <c>, 1
0x8338c    MVN           R3, R3
0x83390    STR           R3,[R0 <d>],4

vs

*d = ~(*d);
d++;
0x83384   LDR           R3,[R0 <d>]
0x83388   ADD           R1 <c>, R1 <c>, 1
0x8338c   MVN           R3, R3
0x83390   STR           R3,[R0 <d>],4

Thanks!

Upvotes: 10

Views: 263

Answers (3)

Christian Rau
Christian Rau

Reputation: 45948

You just do not know when the ++ gets evaluated. I suppose your compiler evaluates it before the ~(*d) which results in

*d = ~(*(d+1));

thus your dicrepancy.

Upvotes: 1

CB Bailey
CB Bailey

Reputation: 791699

*d++ = ~(*d);

In this expression no object is having a new value stored to it more that once. The value of d + 1 is stored to d as a side effect of the incremement operator (d++) and the value of the object pointed to by d before this increment is written to by the assignment operator.

The issue is that d is read, not merely to determine the value to be written back to it (i.e. d + 1) but is also read to determine the address to read from in the right hand side sub-expression ~(*d).

This violates the third sentence of ISO/IEC 14882:2003 5 [expr] / 4 (first sentence omitted for brevity):

[...] Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

Upvotes: 9

Alexandre C.
Alexandre C.

Reputation: 56956

Your expression has undefined (as opposed to unspecified) behavior. The assembly code could as well play Beethoven 9th and still conform to the standard.

From the Holy Standard, Chapter 5, Verse 4:

Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.

Therefore, the code is ill-formed. I don't know whether a standard conforming compiler is required to issue a diagnostic, but I have been bitten enough times by this that I'm ready to bet it is not.

Refer to @Prasoon Saurav's excellent exposition there for more details.

Upvotes: 11

Related Questions