Отключает оператор 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 вызывается для использования системой обработки данных;
Я ожидаю, что это также означает, что в этом международном стандарте не указывается, как статус завершения программы обрабатывается средой хоста.