sequence points in c

An important thing to note about sequence points is that they are not global, but rather should be regarded as a set of local constraints. For example, in the statement

a = f1(x++) + f2(y++);

There is a sequence point between the evaluation of x++ and the call to f1, and another sequence point between the evaluation of y++ and the call to f2. There is, however, no guarantee as to whether x will be incremented before or after f2 is called, nor whether y will be incremented before or after x is called. If f1 changes y or f2 changes x, the results will be undefined (it would be legitimate for the compiler's generated code to e.g. read x and y, increment x, call f1, check y against the previously-read value, and--if it changed--go on a rampage seeking out and destroying all Barney videos and merchandise; I don't think any real compilers generate code that would actually do that, alas, but it would be permitted under the standard).


When a sequence point occurs, it basically means that you are guaranteed that all previous operations are complete.

Changing a variable twice without an intervening sequence point is one example of undefined behaviour.

For example, i = i++; is undefined because there's no sequence point between the two changes to i.

Note that it's not just changing a variable twice that can cause a problem. It's actually a change involved with any other use. The standard uses the term "value computation and side effect" when discussing how things are sequenced. For example, in the expression a = i + i++, the i (value computation) and i++ (side effect) may be done in arbitrary order.

Wikipedia has a list of the sequence points in the C and C++ standards although the definitive list should always be taken from the ISO standard. From C11 appendix C (paraphrased):


The following are the sequence points described in the standard:

  • Between the evaluations of the function designator and actual arguments in a function call and the actual call;
  • Between the evaluations of the first and second operands of the operators &&, ||, and ,;
  • Between the evaluations of the first operand of the conditional ?: operator and whichever of the second and third operands is evaluated;
  • The end of a full declarator;
  • Between the evaluation of a full expression and the next full expression to be evaluated. The following are full expressions:
    • an initializer;
    • the expression in an expression statement;
    • the controlling expression of a selection statement (if or switch);
    • the controlling expression of a while or do statement;
    • each of the expressions of a for statement;
    • the expression in a return statement.
  • Immediately before a library function returns;
  • After the actions associated with each formatted input/output function conversion specifier;
  • Immediately before and immediately after each call to a comparison function, and also between any call to a comparison function and any movement of the objects passed as arguments to that call.