In the C language, a sequence point is a place in code just after the termination of an expression, before any of the ||, &&, ?:, or , operators, or just before a function call, after all of its arguments have been evaluated.

At a sequence point, all variable updates and side-effects since the previous sequence point are guaranteed to have taken place.

From the ISO Standard:

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 accessed only to determine the value to be stored.

The first sentence is pretty obvious: you're not allowed to modify a variable twice between sequence points. (So a statement like i = 5 * i++; is not allowed, because i is both being assigned to, and updated as a side effect of the ++.)

The second sentence is slightly less obvious, and best explained with an example. The behavior of this code: a[i] = i++; is undefined. Why? because the 'prior value' of i is being accessed to determine where in a[], instead of just to compute the value of i++.


Thanks to the comp.lang.c FAQ and some various other web pages for the info, as well as all of my English teachers over the years, who have taught me how to read and comprehend, which assisted greatly in me discovering what sequence points are. Also, thanks to my parents, Ayn Rand and God, who raised me right.

The section of the ANSI/ISO C++ Standard dealing with program execution (1.9) also introduces sequence points.

C++ sequence points happen at the same places as C sequence points:
  • after a full-expression (i.e. an expression that is not a sub expression of another expression, or more succnctly stated, at every semicolon),
  • just after all of the arguments to a function call have been evaluated, and just before the function is called,
  • after the left operand of certain operators (&&, ||, ?:, ,) has been evaulated,
but adds a couple of other places:
  • Just *after* the return value from the function has been copied (possibly by a copy constructor), and just before expressions outside the function (such as a destructor call for some temporary value) are evaulated,
  • Just after a declaration invoking a constructor call with (),
    t_foo foo (bar, baz);
  • After each initializer at the beginning of a constructor definition.

    t_foo::t_foo (/*here*/t_bar ibar, t_baz ibaz): bar (ibar)/*here*/, baz (ibaz)/*here*/
    {
    //some stuff
    };
Notice that all of the above conditions could be interpreted as special cases of the sequence point conditions in C, but are a bit more precise because of things C++ adds.

Finally, the section of the C++ Standard dealing with expressions (5.4) also makes the prohibition against modifying the same lvalue twice without an intervening sequence point.

Source: International Standard ISO-IEC 14882, Programming Languages -- C++, published by the American National Standards Institute, © 1998 Information Technology Industry Council.

Log in or register to write something here or to contact authors.