15

以下代码中的两个赋值之间是否存在序列点:

f(f(x=1,1),x=2);
4

6 回答 6

5

不,没有。在这种情况下,标准确实是模棱两可的。

如果你想确认,gcc 有这个非常酷的选项-Wsequence-point,在这种情况下,它会警告你操作可能是未定义的

于 2011-09-09T02:42:02.037 回答
3

在函数调用的开头和结尾都有序列点。但是,由于函数参数的操作顺序是实现定义的,因此您不能保证f(x=1,1)将在之前执行x=2

另请注意,,函数调用案例中的 不是引入序列点的逗号运算符。

于 2011-09-27T08:27:27.563 回答
3

(草案)标准[6.5.2.2, 10]的相关引用是:

函数指示符、实际参数和实际参数中的子表达式的求值顺序未指定,但在实际调用之前有一个顺序点。

f因此,对于您的表达式,可以在第二个参数之前评估第一个参数(特别是对 的调用);例如:

(x = 1, 1), f <sp> call, (x = 2), f <sp> call

或者,它可以在第二个参数之后进行评估;例如:

(x = 2), (x = 1, 1), f <sp> call, f <sp> call

[函数调用本身可以(并且很可能会)包含更多的序列点(特别是如果它包含一个return语句)。]

取决于此,分配之间是否存在序列点。这取决于平台(“未指定”)。

由于在第二种情况下,您x在两个序列点之间分配了两次,因此您在这样的平台上具有未定义的行为。

于 2011-09-27T11:12:44.930 回答
0

有一个序列点,但外部函数参数的评估顺序(及其副作用)仍未定义。该实现可以自由地首先评估内部 f(),其副作用 x=1,或第二个参数,其副作用 x=2。

于 2011-09-09T10:31:15.270 回答
-3

是的,因为在函数调用之前和之后有一个序列点。

标准的§1.0.17 说:

调用函数时(无论函数是否内联),在对所有函数参数(如果有)求值之后都会有一个序列点,该序列点发生在函数体中的任何表达式或语句执行之前。在复制返回值之后和执行函数外的任何表达式之前还有一个序列点)。

于 2011-09-09T02:36:16.817 回答
-4

是的,由于逗号操作符,会有一个序列点,但结果仍然是未定义的,因为函数参数的评估未定义,因此无法预测该表达式将生成什么值........表示未定义的行为

于 2011-09-27T08:21:12.240 回答