What's the consequence of a sequence-point “immediately before a library function returns”?

早过忘川 提交于 2021-01-27 01:45:09

问题


In this recent question, some code was shown to have undefined behavior:

a[++i] = foo(a[i-1], a[i]);

because even though the actual call of foo() is a sequence point, the assignment is unsequenced, so you don't know whether the function is called after the side-effect of ++i took place or before that.

Thinking further about this, the sequence point at a function call only guarantees that side effects from evaluating the function arguments are carried out once the function is entered, e.g.

int y = 1;
int func1(int x) { return x + y; }
int main(void)
{
    int result = func1( y++ ); // guaranteed to be 3
}

But looking at the standard, there's also §7.1.4 p3 (in the chapter about the standard library):

There is a sequence point immediately before a library function returns.

My question here is: What's the consequence of this paragraph? Why does it only concern library functions and what kind of code would actually rely on that?

Simple ideas like (nonsensical code to follow)

errno = 0;
long result = ftell(file) * errno;

would still be undefined as this time, the multiplication is unsequenced. I'm looking for an example that makes use of this special guarantee §7.1.4 p3 makes for library functions.


Regarding the suggested duplicate, Sequence point after a return statement?, this is indeed closely related and I found it before asking this question. It's not a duplicate, because

  • it asks about normative text stating there is a sequence point immediately after a return, without asking about the consequences when there is one.
  • it only mentions the special rule for library functions this question is about, without further elaborating on it.

Consequently, my questions here are not answered over there. The accepted answer uses a return value in an unsequenced expression (in this case an addition) and explains how the result depends on the sequencing of this addition, only finding that if you knew the sequencing of the addition, the whole result would be defined with a sequence point immediately after return. It doesn't show an example of code that is actually defined because of this rule, and it doesn't say anything about how/why library functions are special.


回答1:


Library functions don't have the code that implements them covered by the standard (they might not even be implemented in C). The standard only specifies their behaviour. So the provision about return statements does not apply to implementation of library functions.

The purpose of this clause (in combination with there being a sequence point on entry of a library function) is to say that any side-effects of the library functions are sequenced either before or after any other evaluations that might be in the code which calls the library function.

So the example in your question is not undefined behaviour (unless the multiplication overflows!): the read of errno is either sequenced before or after the modification by ftell, it's unspecified which.



来源:https://stackoverflow.com/questions/45814572/whats-the-consequence-of-a-sequence-point-immediately-before-a-library-functio

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