Подтвердить что ты не робот

Какое последствие точки последовательности "непосредственно перед возвратом функции библиотеки"?

В этом недавнем вопросе было показано, что некоторый код имеет поведение undefined:

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

потому что хотя фактический вызов foo() является точкой последовательности, назначение не имеет последовательности, поэтому вы не знаете, вызвана ли функция после того, как побочный эффект ++i произошел или до этого.

Подумав об этом, точка последовательности вызова функции только гарантирует, что побочные эффекты от оценки аргументов функции выполняются после ввода функции, например.

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

Но, глядя на стандарт, там также §7.1.4 p3 (в главе о стандартной библиотеке):

Существует точка последовательности непосредственно перед возвратом функции библиотеки.

Мой вопрос здесь: Какое следствие этого параграфа? Почему это относится только к библиотечным функциям и какой код на самом деле полагается на это?

Простые идеи, такие как (бессмысленный код)

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

по-прежнему будет undefined, как это время, умножение не имеет последствий. Я ищу пример, который использует эту специальную гарантию. §7.1.4. P3 выполняет функции библиотеки.


Что касается предлагаемого дубликата, Последовательность после утверждения return?, это действительно тесно связано, и я нашел его, прежде чем задавать этот вопрос. Это не дубликат, потому что

  • он спрашивает о нормативном тексте, в котором указывается точка последовательности сразу после return, не спрашивая о последствиях, когда она есть.
  • в нем упоминается только специальное правило для функций библиотеки Этот вопрос, без дальнейшего уточнения.

Следовательно, на мои вопросы здесь нет ответа. В принятом ответе используется возвращаемое значение в выражении без последствий (в данном случае добавление) и объясняется, как результат зависит от последовательности этого добавления, только если вы обнаружите, что если бы вы знали последовательность добавления, весь результат был бы определен с помощью точка последовательности сразу после return. Он не показывает пример кода, который фактически определен из-за этого правила, и он ничего не говорит о том, как/почему функции библиотеки являются особенными.

4b9b3361

Ответ 1

Функции библиотеки не имеют кода, который реализует их, охватываемых стандартом (они могут быть даже не реализованы на языке C). Стандарт определяет только их поведение. Таким образом, положение о операторах return не применяется к реализации библиотечных функций.

Цель этого предложения (в сочетании с наличием точки последовательности при входе в библиотечную функцию) заключается в том, что любые побочные эффекты библиотечных функций секвенируются либо до, либо после любых других оценок, которые могут быть в код, вызывающий библиотечную функцию.

Итак, пример в вашем вопросе - это не поведение undefined (если переполнение не переполняется!): чтение errno выполняется либо до или после модификации на ftell, но и не указано.