Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 642
Mav3rick Avatar asked May 16 '11 21:05

Mav3rick


2 Answers

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.

like image 174
Alexandre C. Avatar answered Nov 09 '22 22:11

Alexandre C.


*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.

like image 26
CB Bailey Avatar answered Nov 10 '22 00:11

CB Bailey