序列点在c

Jag*_*gan 29 c sequence-points

命令式编程中的序列点定义了计算机程序执行中的任何点,在该点处保证先前评估的所有副作用都已执行,并且尚未执行后续评估的副作用.

这是什么意思?有人可以用简单的语言解释一下吗?

pax*_*blo 42

当序列点出现时,它基本上意味着您可以保证所有先前的操作都已完成.

在没有插入序列点的情况下更改变量两次是未定义行为的一个示例.

例如,i = i++;未定义,因为两个更改之间没有序列点i.

维基百科有一个C和C++标准中的序列点列表,尽管最终列表应始终取自ISO标准.来自C99附录C:


以下是5.1.2.3中描述的序列点:

  • 在评估参数之后调用函数(6.5.2.2).
  • 以下运算符的第一个操作数的结尾:logical AND &&(6.5.13); 逻辑OR || (6.5.14); 条件?(6.5.15); 逗号,(6.5.17).
  • 完整声明者的结尾:声明者(6.7.5);
  • 完整表达式的结束:初始化器(6.7.8); 表达式中的表达式(6.8.3); 选择语句的控制表达式(if或switch)(6.8.4); while或do语句的控制表达式(6.8.5); for语句的每个表达式(6.8.5.3); 返回语句中的表达式(6.8.6.4).
  • 在库函数返回之前(7.1.4).
  • 在与每个格式化的输入/输出函数转换说明符(7.19.6,7.24.2)相关联的操作之后.
  • 紧接在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为参数传递给该调用的对象的任何移动之间(7.20.5).

C11改变了措辞.它似乎打破了三元运算符并添加了一些更多细节:


以下是5.1.2.3中描述的序列点:

  • 在函数调用和实际调用中的函数指示符和实际参数的评估之间.(6.5.2.2).
  • 在以下运算符的第一个和第二个操作数的计算之间:逻辑AND &&(6.5.13); 逻辑OR || (6.5.14); 逗号,(6.5.17).
  • 在条件?:运算符的第一个操作数的评估与第二个和第三个操作数中的任何一个之间进行评估(6.5.15).
  • 完整声明者的结尾:声明者(6.7.6);
  • 在评估完整表达式和下一个要评估的完整表达式之间.以下是完整表达式:初始化程序(6.7.9); 表达式中的表达式(6.8.3); 选择语句的控制表达式(if或switch)(6.8.4); while或do语句的控制表达式(6.8.5); for语句的每个表达式(6.8.5.3); 返回语句中的表达式(6.8.6.4).
  • 在库函数返回之前(7.1.4).
  • 在与每个格式化的输入/输出函数转换说明符(7.21.6,7.28.2)相关联的操作之后.
  • 紧接在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为参数传递给该调用的对象的任何移动之间(7.22.5).

  • 修改变量的值以及以其他方式使用该值(除了确定没有中间顺序点的情况下要存储的值)之外,这也是未定义的行为。例如,a [i ++] = i是未定义的,因为尽管它仅修改i的值一次,但i的值用于确定存储在i中的值以外的目的。 (2认同)

sup*_*cat 10

需要注意顺序点的一个重要的事情是,他们不是全球性的,而应该被视为一组局部约束.例如,在声明中

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

有x的计算++和呼叫于f1,和y的评价++和呼叫到f2之间另一序列点之间的序列点.有,但是,不能保证是否x将之前或F2被称为后递增,也不确定y会前或x称为后递增.如果f1改变y或f2改变x,则结果将是未定义的(编译器生成的代码例如读取x和y,递增x,调用f1,检查y与先前读取的值,以及 - 如果它改变了 - 继续横冲直撞寻找并摧毁所有Barney的视频和商品;我认为任何真正的编译器都不会产生实际上会这样做的代码,唉,但它会被允许在标准之下).


Joh*_*ode 7

用一个例子扩展 paxdiablo 的答案。

假设声明

x = i++ * ++j;
Run Code Online (Sandbox Code Playgroud)

存在三个副作用:将 的结果赋值i * (j+1)给 x、i 加 1、j 加 1。副作用的应用顺序未指定;i 和 j 可以在评估后立即递增,或者直到两者都评估之后但在分配 x 之前才可以递增,或者它们可以在分配 x 之后才递增。

序列点是所有副作用均已应用的点(x、i 和 j 均已更新),无论它们应用的顺序如何。

  • 然而,我们应该指出,`x = i++ * ++j` 的结果是明确定义的,与 paxdiablo 的 `i = i++` 示例不同...... (14认同)