В этом недавнем вопросе было показано, что некоторый код имеет неопределенное поведение:
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;
по-прежнему будет неопределенным, так как на этот раз умножение не упорядочено. Я ищу пример, который использует эту специальную гарантию §7.1.4 p3 для библиотечных функций.
Что касается предлагаемого дубликата, точка последовательности после оператора return?, это действительно тесно связано, и я нашел его, прежде чем задать этот вопрос . Это не дубликат, потому что
- он спрашивает о нормативном тексте, утверждающем, что есть точка следования сразу после
return
, не спрашивая о последствиях, когда она есть. - в нем упоминается только специальное правило для библиотечных функций, о котором этот вопрос, без дальнейшего уточнения.
Следовательно, на мои вопросы здесь нет ответа там. Принятый ответ использует возвращаемое значение в выражении без последовательности (в данном случае дополнение) и объясняет, как результат зависит от последовательности этого добавления, обнаруживая только это, если бы вы знали последовательность добавления, весь результат будет определяться точкой следования сразу после return
. Он не показывает пример кода, который фактически определен из-за этого правила, и ничего не говорит о том, чем и почему библиотечные функции являются особенными.