[LLVMdev] Why "I = ++I" instead of "++I" in COFFDump.cpp ?

Krzysztof Parzyszek kparzysz at codeaurora.org
Tue Apr 8 10:35:24 PDT 2014


On 4/8/2014 11:39 AM, Richard wrote:
>
> In article <CAOfiQq=gtrW-qHLLn-5bfmwZ6Qr4wv3mi=NP78AetEOpbTJVqA at mail.gmail.com>,
>      Richard Smith <richard at metafoo.co.uk> writes:
>
>> On Mon, Apr 7, 2014 at 12:09 PM, Joerg Sonnenberger <joerg at britannica.bec.de
>>> wrote:
>>
>>> It is a bug as it violates the sequence point rule. One memory location
>>> shall not be modified twice.
>>
>>
>> Not in C++11, and (probably) not in C11. The side-effect of pre-increment
>> is sequenced before its value computation, and its value computation is
>> sequenced before the assignment. (C++ doesn't have sequence points any
>> more, and C only has them as a vestigial remnant of the pre-memory-model
>> world.)
>
> OK, still looking on how to find this in the standard.

C99:

6.5 Expressions
1 An expression is a sequence of operators and operands that specifies 
computation of a value, or that designates an object or a function, or 
that generates side effects, or that performs a combination thereof.
2 Between the previous and next sequence point an object shall have its 
stored value modified at most once by the evaluation of an expression. 
Furthermore, the prior value shall be read only to determine the value 
to be stored.70)

70) This paragraph renders undefined statement expressions such as
   i = ++i + 1;
   a[i++] = i;
while allowing
   i = i + 1;
   a[i] = i;



C++ 2003:

5 Expressions
[...]
4 Except where noted, the order of evaluation of operands of individual 
operators and subexpressions of individual expressions, and the order in 
which side effects take place, is unspecified.53) 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. [Example:
   i = v[i++]; // the behavior is unspecified
   i = 7, i++, i++; // i becomes 9
   i = ++i + 1; // the behavior is unspecified
   i = i + 1; // the value of i is incremented
—end example]

53) The precedence of operators is not directly specified, but it can be 
derived from the syntax.



C++ working draft:

1.9 Program execution
[...]
13 Sequenced before is an asymmetric, transitive, pair-wise relation 
between evaluations executed by a single thread (1.10), which induces a 
partial order among those evaluations. Given any two evaluations A and 
B, if A is sequenced before B, then the execution of A shall precede the 
execution of B. If A is not sequenced before B and B is not sequenced 
before A, then A and B are unsequenced. [ Note: The execution of 
unsequenced evaluations can overlap. —end note ] Evaluations A and B are 
indeterminately sequenced when either A is sequenced before B or B is 
sequenced before A, but it is unspecified which. [ Note: Indeterminately 
sequenced evaluations cannot overlap, but either could be executed 
first. —end note ]
14 Every value computation and side effect associated with a 
full-expression is sequenced before every value computation and side 
effect associated with the next full-expression to be evaluated.8)
15 Except where noted, evaluations of operands of individual operators 
and of subexpressions of individual expressions are unsequenced. [ Note: 
In an expression that is evaluated more than once during the execution 
of a program, unsequenced and indeterminately sequenced evaluations of 
its subexpressions need not be performed consistently in different 
evaluations. —end note ] The value computations of the operands of an 
operator are sequenced before the value computation of the result of the 
operator. If a side effect on a scalar object is unsequenced relative to 
either another side effect on the same scalar object or a value 
computation using the value of the same scalar object, and they are not 
potentially concurrent (1.10), the behavior is
undefined. [ Note: The next section imposes similar, but more complex 
restrictions on potentially concurrent computations. —end note ]
[ Example:
   void f(int, int);
   void g(int i, int* v) {
     i = v[i++]; // the behavior is undefined
     i = 7, i++, i++; // i becomes 9
     i = i++ + 1; // the behavior is undefined
     i = i + 1; // the value of i is incremented
     f(i = -1, i = -1); // the behavior is undefined
   }
—end example ]
When calling a function (whether or not the function is inline), every 
value computation and side effect associated with any argument 
expression, or with the postfix expression designating the called 
function, is sequenced before execution of every expression or statement 
in the body of the called function. [ Note: Value computations and side 
effects associated with different argument expressions are unsequenced. 
—end note ] Every evaluation in the calling function (including other 
function calls) that is not otherwise specifically sequenced before or 
after the execution of the body of the called function is 
indeterminately sequenced with respect to the execution of the called 
function.9) Several contexts in C++ cause evaluation of a function call, 
even though no corresponding function call syntax appears in the 
translation unit. [ Example: Evaluation of
a new expression invokes one or more allocation and constructor 
functions; see 5.3.4. For another example, invocation of a conversion 
function (12.3.2) can arise in contexts in which no function call syntax 
appears. —end example ] The sequencing constraints on the execution of 
the called function (as described above) are features of the function 
calls as evaluated, whatever the syntax of the expression that calls the 
function might be.

8) As specified in 12.2, after a full-expression is evaluated, a 
sequence of zero or more invocations of destructor functions for
temporary objects takes place, usually in reverse order of the 
construction of each temporary object.
9) In other words, function executions do not interleave with each other.


HTH,
-Krzysztof


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation



More information about the llvm-dev mailing list