Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>This is a follow up to my <a href="https://stackoverflow.com/questions/4176328/faq-undefined-behavior-and-sequence-points/4176333#4176333">previous answer</a> and contains C++11 related material.</strong>.</p> <hr> <p><strong>Pre-requisites</strong> : An elementary knowledge of Relations (Mathematics).</p> <hr> <h2>Is it true that there are no Sequence Points in C++11?</h2> <p><strong>Yes!</strong> This is very true. </p> <p><strong>Sequence Points</strong> have been replaced by <strong>Sequenced Before</strong> and <strong>Sequenced After</strong> (and <strong>Unsequenced</strong> and <strong>Indeterminately Sequenced</strong>) <a href="http://en.wikipedia.org/wiki/Relation_(mathematics)" rel="noreferrer">relations</a> in C++11.</p> <hr> <h2>What exactly is this 'Sequenced before' thing?</h2> <p><strong>Sequenced Before</strong><sup>(§1.9/13)</sup> is a relation which is: </p> <ul> <li><a href="http://en.wikipedia.org/wiki/Asymmetric_relation" rel="noreferrer"><strong>Asymmetric</strong></a> </li> <li><a href="http://en.wikipedia.org/wiki/Transitive_relation" rel="noreferrer"><strong>Transitive</strong></a></li> </ul> <p>between evaluations executed by a single <a href="http://en.wikipedia.org/wiki/Thread_(computer_science)" rel="noreferrer">thread</a> and induces a <strong>strict partial order</strong><sup>1</sup><br></p> <p>Formally it means given any two evaluations<sup>(See below)</sup> <code>A</code> and <code>B</code>, if <code>A</code> is <strong>sequenced before</strong> <code>B</code>, then the execution of <code>A</code> <em>shall precede</em> the execution of <code>B</code>. If <code>A</code> is not sequenced before <code>B</code> and <code>B</code> is not sequenced before <code>A</code>, then <code>A</code> and <code>B</code> are <strong>unsequenced</strong> <sup>2</sup>.</p> <p>Evaluations <code>A</code> and <code>B</code> are <strong>indeterminately sequenced</strong> when either <code>A</code> is sequenced before <code>B</code> or <code>B</code> is sequenced before <code>A</code>, but it is unspecified which<sup>3</sup>.</p> <p><sub>[NOTES]</sub> <sub><br> 1 : A strict partial order is a <a href="http://en.wikipedia.org/wiki/Binary_relation" rel="noreferrer"><strong>binary relation</strong></a> <code>"&lt;"</code> over a set <code>P</code> which is <a href="http://en.wikipedia.org/wiki/Asymmetric_relation" rel="noreferrer"><code>asymmetric</code></a>, and <a href="http://en.wikipedia.org/wiki/Transitive_relation" rel="noreferrer"><code>transitive</code></a>, i.e., for all <code>a</code>, <code>b</code>, and <code>c</code> in <code>P</code>, we have that:<br> </sub> <sub> ........(i). if a &lt; b then ¬ (b &lt; a) (<code>asymmetry</code>);<br> ........(ii). if a &lt; b and b &lt; c then a &lt; c (<code>transitivity</code>).<br> 2 : The execution of <strong>unsequenced evaluations</strong> can <em>overlap</em>.<br> 3 : <strong>Indeterminately sequenced evaluations</strong> cannot <em>overlap</em>, but either could be executed first. </sub></p> <hr> <h2> What is the meaning of the word 'evaluation' in context of C++11? </h2> <p>In C++11, evaluation of an expression (or a sub-expression) in general includes: </p> <ul> <li><p><strong>value computations</strong> (including determining the identity of an object for <a href="https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues">glvalue evaluation</a> and fetching a value previously assigned to an object for <a href="https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues">prvalue evaluation</a>) and</p></li> <li><p>initiation of <strong>side effects</strong>.</p></li> </ul> <p>Now (§1.9/14) says:</p> <blockquote> <p>Every value computation and side effect associated with a full-expression is <strong>sequenced before</strong> every value computation and side effect associated with the <strong>next full-expression to be evaluated</strong>.</p> </blockquote> <ul> <li><p>Trivial example: </p> <p><code>int x;</code> <code>x = 10;</code> <code>++x;</code></p> <p>Value computation and side effect associated with <code>++x</code> is sequenced after the value computation and side effect of <code>x = 10;</code> </p></li> </ul> <hr> <h2>So there must be some relation between Undefined Behaviour and the above-mentioned things, right? </h2> <p><strong>Yes!</strong> Right.</p> <p>In (§1.9/15) it has been mentioned that </p> <blockquote> <p>Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are <strong>unsequenced</strong><sup>4</sup>.</p> </blockquote> <p>For example :</p> <pre><code>int main() { int num = 19 ; num = (num &lt;&lt; 3) + (num &gt;&gt; 3); } </code></pre> <ol> <li>Evaluation of operands of <code>+</code> operator are unsequenced relative to each other.</li> <li>Evaluation of operands of <code>&lt;&lt;</code> and <code>&gt;&gt;</code> operators are unsequenced relative to each other.</li> </ol> <p><sub> 4: In an expression that is evaluated more than once during the execution of a program, <strong>unsequenced</strong> and <strong>indeterminately sequenced</strong> evaluations of its subexpressions need not be performed consistently in different evaluations. </sub></p> <blockquote> <p>(§1.9/15) The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.</p> </blockquote> <p>That means in <code>x + y</code> the value computation of <code>x</code> and <code>y</code> are sequenced before the value computation of <code>(x + y)</code>.</p> <p>More importantly</p> <blockquote> <p>(§1.9/15) If a side effect on a scalar object is unsequenced relative to either</p> <p>(a) <strong>another side effect on the same scalar object</strong> </p> <p>or </p> <p>(b) <strong>a value computation using the value of the same scalar object.</strong></p> <p>the behaviour is <strong>undefined</strong>.</p> </blockquote> <p>Examples:</p> <pre><code>int i = 5, v[10] = { }; void f(int, int); </code></pre> <ol> <li><code>i = i++ * ++i; // Undefined Behaviour</code></li> <li><code>i = ++i + i++; // Undefined Behaviour</code> </li> <li><code>i = ++i + ++i; // Undefined Behaviour</code></li> <li><code>i = v[i++]; // Undefined Behaviour</code></li> <li><code>i = v[++i]: // Well-defined Behavior</code></li> <li><code>i = i++ + 1; // Undefined Behaviour</code></li> <li><code>i = ++i + 1; // Well-defined Behaviour</code></li> <li><code>++++i; // Well-defined Behaviour</code></li> <li><code>f(i = -1, i = -1); // Undefined Behaviour (see below)</code></li> </ol> <blockquote> <p>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. [<em>Note:</em> <strong>Value computations and side effects associated with different argument expressions are unsequenced</strong>. — <em>end note</em>]</p> </blockquote> <p>Expressions <code>(5)</code>, <code>(7)</code> and <code>(8)</code> do not invoke undefined behaviour. Check out the following answers for a more detailed explanation.</p> <ul> <li><a href="https://stackoverflow.com/questions/3690141/multiple-preincrement-operations-on-a-variable-in-cc/3691469#3691469">Multiple preincrement operations on a variable in C++0x</a></li> <li><a href="https://stackoverflow.com/questions/3852768/unsequenced-value-computations-a-k-a-sequence-points/3852774#3852774">Unsequenced Value Computations</a></li> </ul> <hr> <p><strong>Final Note</strong> : </p> <p>If you find any flaw in the post please leave a comment. Power-users (With rep >20000) please do not hesitate to edit the post for correcting typos and other mistakes.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload