Отключает оператор return undefined в C89 (aka ANSI C)?

Рассмотрим следующий базовый пример:

#include <stdio.h>

int main(void)
{
    printf("Hi there!\n");
}

Он вызывает поведение undefined в C89? Я попытался получить некоторый смысл от этого вопроса, но большинство утвержденных ответов утверждают, что он определен в реализации и определенно не UB здесь (с комментариями Кейта Томпсона, который выглядит противоречиво).

Спектр говорит в §3.16. Определения и условные обозначения:

Если требование "должно" или "не должно", которое появляется за пределами ограничение нарушено. поведение undefined. undefined поведение указывается в этом Международном стандарте словами: "undefined поведение" или путем пропуска любого явного определения поведение. В этих трех различиях нет разницы: они все описывают "поведение, которое undefined".

и §5.1.2.2.3 Окончание программы:

Возврат от начального вызова к функции main эквивалентен вызывая функцию exit со значением, возвращаемым функцией mainкак его аргумент. Если функция main выполняет возврат, указывающий нет значения, статус завершения, возвращаемый в среду хоста, undefined.

Мое понимание заключается в том, что в последнем подпункте не рассматривается случай отсутствия возврата, поскольку оператор return не вызывается никогда, поэтому применяется предыдущий подзапрос.

Однако дальнейшее чтение указывает на что-то другое, §6.6.6.4 Оператор return:

Если выполняется оператор return без выражения, а значение вызова функции используется вызывающим, поведение undefined. Достижение }, которое завершает функцию, эквивалентно выполнению return без выражения.

Итак, теперь применяется подкласс 5.1.2.2.3:

Если функция main выполняет возврат, указывающий неважно. статус завершения, возвращаемый в среду хоста, undefined.

Термин "статус завершения - undefined", по-видимому, не является UB, а не каким-либо конкретным поведением, но больше похоже на него за пределами C-стандарта, думая больше: "пусть принимающей среды, о которой нужно беспокоиться, мы отмываем руки отсюда". Это правильная интуиция?

Ответы

Ответ 1

Несколько лет назад я действительно отлаживал проблемы, вызванные этим. Это становится еще более интересным, если у вас есть коды кода с возвратом и другими без него.

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

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

Ответ 2

Я считаю, что цель Стандартного комитета заключалась в том, что это значение статуса прекращения не указано.

Согласно N739 черновик:

и измените последнее предложение подпункта 5.1.2.2.3 на:

Если функция /main/function выполняет возврат, который не задает значения, статус завершения, возвращаемый в среду хоста, undefined.

в

Если функция /main/function выполняет возврат, который не задает значение, | статус завершения, возвращаемый в среду хоста, неопределенные.

[Концепция значения undefined тщательно избегается в другом месте.]

Вы также можете найти в других Стандартах, что терминология была изменена, и поэтому термин "неуказанный" используется.

Я бы сказал, что он определенно не намерен быть undefined поведением как таковым, но все же невозможно решить, было ли это неопределенное поведение или как я вообще не сказал никакого поведения. Другая выдержка, которая указала бы, что это: §1 Область действия:

В этом международном стандарте не указывается:

  • механизм, с помощью которого программ C вызывается для использования системой обработки данных;

Я ожидаю, что это также означает, что в этом международном стандарте не указывается, как статус завершения программы обрабатывается средой хоста.