c++ - Undefined behavior and sequence points -


what "sequence points"?

what relation between undefined behaviour , sequence points?

i use funny , convoluted expressions a[++i] = i;, make myself feel better. why should stop using them?

if you've read this, sure visit follow-up question undefined behavior , sequence points reloaded.

(note: meant entry stack overflow's c++ faq. if want critique idea of providing faq in form, the posting on meta started this place that. answers question monitored in c++ chatroom, faq idea started out in first place, answer read came idea.)

c++98 , c++03

this answer older versions of c++ standard. c++11 , c++14 versions of standard not formally contain 'sequence points'; operations 'sequenced before' or 'unsequenced' or 'indeterminately sequenced' instead. net effect same, terminology different.


disclaimer : okay. answer bit long. have patience while reading it. if know these things, reading them again won't make crazy.

pre-requisites : elementary knowledge of c++ standard


what sequence points?

the standard says

at specified points in execution sequence called sequence points, side effects of previous evaluations shall complete , no side effects of subsequent evaluations shall have taken place. (§1.9/7)

side effects? side effects?

evaluation of expression produces , if in addition there change in state of execution environment said expression (its evaluation) has side effect(s).

for example:

int x = y++; //where y int 

in addition initialization operation value of y gets changed due side effect of ++ operator.

so far good. moving on sequence points. alternation definition of seq-points given comp.lang.c author steve summit:

sequence point point in time @ dust has settled , side effects have been seen far guaranteed complete.


what common sequence points listed in c++ standard ?

those are:

  • at end of evaluation of full expression (§1.9/16) (a full-expression expression not subexpression of expression.)1

example :

int = 5; // ; sequence point here 
  • in evaluation of each of following expressions after evaluation of first expression(§1.9/18) 2

    • a && b (§5.14)
    • a || b (§5.15)
    • a ? b : c (§5.16)
    • a , b (§5.18) (in func(a,a++) , not comma operator, it's merely separator between arguments a , a++. behaviour undefined in case if a considered primitive type)
  • at function call (whether or not function inline), after evaluation of function arguments (if any) takes place before execution of expressions or statements in function body (§1.9/17).

1 : note : evaluation of full-expression can include evaluation of subexpressions not lexically part of full-expression. example, subexpressions involved in evaluating default argument expressions (8.3.6) considered created in expression calls function, not expression defines default argument

2 : operators indicated built-in operators, described in clause 5. when 1 of these operators overloaded (clause 13) in valid context, designating user-defined operator function, expression designates function invocation , operands form argument list, without implied sequence point between them.


what undefined behaviour?

the standard defines undefined behaviour in section §1.3.12 as

behaviour, such might arise upon use of erroneous program construct or erroneous data, international standard imposes no requirements 3.

undefined behaviour may expected when international standard omits description of explicit definition of behavior.

3 : permissible undefined behavior ranges ignoring situation unpredictable results, behaving during translation or program execution in documented manner characteristic of environment (with or with- out issuance of diagnostic message), terminating translation or execution (with issuance of diagnostic message).

in short, undefined behaviour means anything can happen daemons flying out of nose girlfriend getting pregnant.


what relation between undefined behaviour , sequence points?

before must know difference(s) between undefined behaviour, unspecified behaviour , implementation defined behaviour.

you must know the order of evaluation of operands of individual operators , subexpressions of individual expressions, , order in side effects take place, unspecified.

for example:

int x = 5, y = 6;  int z = x++ + y++; //it unspecified whether x++ or y++ evaluated first. 

another example here.


now standard in §5/4 says

  • 1) between previous , next sequence point scalar object shall have stored value modified @ once evaluation of expression.

what mean?

informally means between 2 sequence points variable must not modified more once. in expression statement, next sequence point @ terminating semicolon, , previous sequence point @ end of previous statement. expression may contain intermediate sequence points.

from above sentence following expressions invoke undefined behaviour:

i++ * ++i;   // ub, modified more once btw 2 sps = ++i;     // ub, same above ++i = 2;     // ub, same above = ++i + 1; // ub, same above ++++++i;     // ub, parsed (++(++(++i)))  = (i, ++i, ++i); // ub, there's no sp between `++i` (right most) , assignment `i` (`i` modified more once btw 2 sps) 

but following expressions fine:

i = (i, ++i, 1) + 1; // defined (afaik) = (++i, i++, i);   // defined  int j = i; j = (++i, i++, j*i); // defined 

  • 2) furthermore, prior value shall accessed determine value stored.

what mean? means if object written within full expression, , accesses within same expression must directly involved in computation of value written.

for example in i = + 1 access of i (in l.h.s , in r.h.s) directly involved in computation of value written. fine.

this rule constrains legal expressions in accesses demonstrably precede modification.

example 1:

std::printf("%d %d", i,++i); // invokes undefined behaviour because of rule no 2 

example 2:

a[i] = i++ // or a[++i] = or a[i++] = ++i etc 

is disallowed because 1 of accesses of i (the 1 in a[i]) has nothing value ends being stored in (which happens on in i++), , there's no way define--either our understanding or compiler's--whether access should take place before or after incremented value stored. behaviour undefined.

example 3 :

int x = + i++ ;// similar above 

follow answer here.


Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

html - Instapaper-like algorithm -

c# - How to execute a particular part of code asynchronously in a class -