Sequence point after a return statement?

跟風遠走 提交于 2019-12-19 09:22:36

问题


In my answer to a question here I explained what happened when postfix ++ was used on a global variable on the same line as a return statement.

The informative appendix C of C11 states that there is a sequence point immediately after a return and refers to normative chapter 6.8.6.4, where no text regarding sequence points can be found.

Where in the C standard can I find normative text stating that there is a sequence point after a return statement?

(I only found normative text stating this for library functions, as a special case, at 7.1.4/3.)


回答1:


C 2011 (draft n1570) 6.8 4: “Each of the following is a full expression: … the (optional) expression in a return statement. There is a sequence point between the evaluation of a full expression and the evaluation of the next full expression to be evaluated.”

So technically the sequence point is not after a return but is between the evaluation of the expression in the return and the next expression. Consider this code, called when a is initially 0:

int a = 0;

int Foo(void) { return a++; }

void Bar(void)
{
    int b = Foo() + a;
    …
}

In Foo() + a, whether Foo() or a is evaluated first is unspecified. We will consider both orders in light of both potential rules (sequence point after return versus sequence point between the expression of the return and the next full expression). If the implementation does a first, then it must do:

a
Sequence point
Foo()
+

and then some other full expression would follow, so, by either rule, there would be a sequence point, and this code is the same either way, as far as we are concerned. The result is that b is set to 0.

If the implementation does Foo() first, then, with the “sequence pointer after a return” rule, the implementation must do:

Sequence point
Foo()
Sequence point
a
+

This code would have defined behavior: a is incremented by the side effect in Foo, and that is complete before a is accessed, then + is performed. The result is that a is set to 1. Although the result may be 0 or 1 with this “sequence point after return” rule, it is merely unspecified which of the two orders is used; the behavior is not completely undefined.

However, if the implementation does Foo() first and uses the standard C rule of “sequence point between the expression of a return and the next full expression”, then we have:

Sequence point
Foo()
???
a
???
+
???

The “???” mark places where the required sequence point might be—anywhere after the return and before the next full expression. In this case, the value of a might be accessed in a and modified in Foo(), and there is no intervening sequence point. That is undefined behavior.

Therefore, the rule “sequence point after the expression of a return and before next full expression” is different from “sequence point immediately after a return”; the first has undefined behavior in this example, and the second does not.




回答2:


I don't think you're going to find what you're looking for. no text regarding sequence points can be found that's true, it's only implied by section 6.8 p4.

The C++ standard (ISO/IEC 14882:2003) in section 1.9 (footnote 11) states the fact that a sequence point after the return is not explicitily written anywhere in the C standards:

11) The sequence point at the function return is not explicitly specified in ISO C, and can be considered redundant with sequence points at full-expressions, but the extra clarity is important in C + +. In C + +, there are more ways in which a called function can terminate its execution, such as the throw of an exception.



来源:https://stackoverflow.com/questions/15637678/sequence-point-after-a-return-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!