c – 返回对象的函数调用和该对象上的方法调用之间是否存在序列点?
作者:互联网
如果我写f(x) – > g(args,…)我可以依赖于f(x)之后的序列点来评估args,…?我可以通过两种方式看到论点:
>§1.9.17“当调用函数时(无论函数是否为内联函数),在评估函数体中任何表达式或语句之前发生的所有函数参数(如果有)之后都有一个序列点在复制返回值之后和执行函数之外的任何表达式之前,还有一个序列点.“
>另一方面,对象指针隐含地是一个隐藏的参数,就好像我写了g(f(x),args,…),这表明它就像一个参数,因此未指定.
– >运算符不是普通的二元运算符,因为在f(x)之前,如果我写f(x)g(…),就不能像g(…)那样进行评估.我很惊讶我找不到一些具体的说法.
解决方法:
答案取决于您使用的C标准版本(或您的编译器正在使用).
C 2003 5.2.2 p8说:
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.
这意味着在评估f(x)和args之间没有序列点.
在C 2011中,序列点的整个概念已经被替换(见N1944),这个措辞现在只是一个注释:
[ Note: The evaluations of the postfix expression and of the argument expressions are all unsequenced relative to one another. All side effects of argument expression evaluations are sequenced before the function is entered (see 1.9). — end note ]
和1.9 p15说
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. — end note ]
这表示表达式f(x)和表达式args在g体中的所有内容之前排序,但是它们相对于彼此没有排序,这与C 03规则相同但措辞不同.
C 14与C 11具有相同的规则,但如下面的评论所述,规则在C 17中有所改变.
C 2017 8.2.2 [expr.call] p5说:
The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.
这意味着您的示例将按顺序执行以下步骤:
> f被评估.
>评估x并初始化f的参数.
>评估函数调用f(x).
评估> f(x) – > g.
> args和g的其他参数被计算,并且g的参数被初始化(以未指定的顺序).
>最后,评估函数调用f(x) – > g(args,…).
标签:c,sequence-points,unspecified-behavior 来源: https://codeday.me/bug/20191001/1838264.html