以下代码中的两个赋值之间是否存在序列点:
f(f(x=1,1),x=2);
答案 0 :(得分:5)
不,没有。在这种情况下,标准确实含糊不清。
如果你想确认一下,gcc有这个非常酷的选项-Wsequence-point
,在这种情况下它会警告你操作可能是未定义的
答案 1 :(得分:3)
在函数调用开始时和结束时有序列点。但是,由于函数参数的操作顺序是实现定义的,因此您无法保证f(x=1,1)
将在x=2
之前执行。
另请注意,函数调用案例中的,
不是引入序列点的逗号运算符。
答案 2 :(得分:3)
the (draft) standard [6.5.2.2,10]的相关引用是:
功能指示符的评估顺序, 实际的参数和子表达式 实际参数未指定,但有一个序列 在实际通话之前指出。
因此,对于您的表达式,第一个参数(特别是对f
的调用)可能是
在第二个论点之前评估; e.g:
(x = 1, 1), f <sp> call, (x = 2), f <sp> call
或者,它可以在第二个参数之后进行评估;例如:
(x = 2), (x = 1, 1), f <sp> call, f <sp> call
[函数调用本身可以(并且很可能会)包含更多序列点(特别是如果它包含return
语句)。]
根据不同,指定之间是否存在序列点。 这取决于平台(“未指定”)。
因为在第二种情况下,您在两个序列点之间分配x
两次,所以在这样的平台上有未定义的行为。
答案 3 :(得分:0)
有一个序列点,但外部函数参数的评估顺序(及其副作用)仍未定义。实现可以自由地首先评估内部f(),其副作用x = 1,或第二个参数,副作用x = 2.
答案 4 :(得分:-3)
是的,因为在函数调用之前和之后都有一个序列点。
该标准的§1.0.17说:当调用函数时(无论函数是否为内联函数),那里 是评估所有函数参数后的序列点(如果 任何)在执行任何表达式之前发生的 函数体中的语句。之后还有一个序列点 复制返回值并在执行任何之前 函数外的表达式。)
答案 5 :(得分:-4)
是的,由于逗号操作符会有一个序列点但是由于函数参数的评估是未定义的,因此无法定义结果,因此无法预测此表达式将生成的值........表示未定义的行为< / p>