顺序点

顺序点，也称作序列点，是计算机程序中一些执行点，在该点处之前的求值的所有的副作用已经发生，在它之后的求值的所有副作用仍未开始。在C与C++程序设计语言中，表达式的值依赖于它的子表达式的求值顺序。增加更多的顺序点限制了可能的求值顺序，能保证有一个一致结果。

C++11中，顺序点概念已经被sequenced before这种方法取代：直接指出一个求值是在另一个求值之前，或者两个求值是无顺序的。无顺序的求值可以重叠进行。

歧义例子
考虑两个函数f()与g()。在C与C++中，加法运算符+不是一个顺序点，因此表达式f() + g()可能会先调用f()，或先调用g()。逗号运算符引入了一个顺序点，因此表达式f(), g()的求值顺序是确定的：首先调用f()，然后调用g()。

当一个变量在一个表达式修改不止一次，顺序点也发挥作用。一个典型的C语言例子是表达式i = i++，其中i的结果值是有二义性的，依赖于表达式求值顺序：自增运算可能发生在赋值之前、之后或者交错进行。在C与C++语言中，这会导致未定义行为。

C与C++的顺序点
在C与C++中，顺序点出现在下述位置：（C++的重载操作符的行为类似于函数） 
&&（逻辑与）、||（逻辑或）、逗号运算符的左操作数与右操作数求值之间（前两者是短路求值的一部分）。例如，表达式*p++ != 0 && *q++ != 0，子表达式*p++ != 0的副作用都会在试图访问q之前完成。
三元条件运算符的第一个操作数之后，第二或第三操作数之前。例如，表达式a = (*p++) ? (*p++) : 0在第一个*p++之后存在顺序点，因而在第二个*p++求值之前已经做完一次自增。
完整表达式结束处。包括表达式语句（如赋值a = b;），返回语句，if、switch、while、do-while语句的控制表达式，for语句的3个表达式。
函数调用时的函数入口点。函数实参的求值顺序未指定，但顺序点意味着这些实参求值的副作用在进入函数时都已经完成。表达式f(i++) + g(j++) + h(k++)，调用f(), g(), h()的顺序未指定，i, j, k的自增顺序也未指定。函数调用f(a,b,c)的实参列表不是逗号运算符，a, b, c的求值顺序未指定。
函数返回时，在返回值已经复制到调用上下文。（仅C++标准指出这一顺序点)
初始化的结束。例如，声明int a = 5;中的对5求值之后。
初始化列表的以逗号分割的各个初始化值，严格遵照从左至右求值。例如：int a[3] = {i++,j--,foo(101)};注意，此处不是逗号运算符。（从C++11标准指出这一顺序点）
在声明序列的每个声明（declarator）之间。例如，int x = a++, y = a++的两次a++求值之间。注意，此例不是逗号运算符。

参考文献

Question 3.8  of the FAQ for comp.lang.c

 
C語言
C++