Как отметил Дженс в комментарии, опубликованный код не проявляет неопределенного поведения. Первоначальный ответ здесь не верен и, похоже, на самом деле даже не отвечает на вопрос (перечитывая все через несколько лет).
Вопрос можно сформулировать так: «Почему MSVC не выдает предупреждение C4716 для main()
при тех же обстоятельствах, что и для других функций»?
Обратите внимание, что диагностика C4716 является предупреждением, а не ошибкой. Что касается языка Си (в любом случае, с точки зрения стандартов), то нет необходимости диагностировать отсутствие ошибок. но это на самом деле не объясняет, почему есть разница, это просто техническая специфика, которая может означать, что вы не можете жаловаться слишком много ...
Реальное объяснение того, почему MSVC не выдает предупреждение для main()
, когда это происходит для других функций, действительно может ответить только кто-то из команды MSVC. Насколько я могу судить, документы не объясняют разницу, но, возможно, я что-то упустил; так что все, что я могу сделать, это спекулировать:
В C ++ функция main()
обрабатывается специально в том смысле, что перед закрывающей скобкой есть неявный return 0;
.
Я подозреваю, что компилятор Microsoft C обеспечивает такую же обработку при компиляции в режиме C (если вы посмотрите на код сборки, регистр EAX очищается, даже если нет return 0;
), поэтому в том, что касается компилятора нет причин выдавать предупреждение C4716. Обратите внимание, что режим Microsoft C совместим с C90, а не с C99. В C90 «бег в конец» main()
имеет неопределенное поведение. Однако всегда возвращаемый 0 соответствует низким требованиям неопределенного поведения, поэтому проблем нет.
Таким образом, даже если бы программа в вопросе не выполнила до конца main()
(что привело к неопределенному поведению), все равно не было бы предупреждения.
Оригинальный, не очень хороший ответ:
В ANSI / ISO 90 C это неопределенное поведение, поэтому MS действительно должна выдавать ошибку (но это не требуется стандартом). В C99 стандарт допускает подразумеваемый return
в конце main () - как и в C ++.
Так что, если это скомпилировано как C ++ или C99, ошибки нет, и это то же самое, что и return 0;
. C90 приводит к неопределенному поведению (которое не требует диагностики).
Интересно (ну, может быть, и нет), из нескольких компиляторов (VC9, VC6, GCC 3.4.5, Digital Mars, Comeau) Я попробовал это с моими базовыми, в основном, настройками по умолчанию (среда, которую я почти всегда использую для быстрого и детального тестирования фрагментов кода) единственный компилятор, который предупреждает об отсутствующем операторе возврата, - это VC6 при компиляции в виде программы на C ++ (VC6 не жалуется при компиляции для C).
Большинство компиляторов жалуются (предупреждение или ошибка), если функция не названа main
. Digital Mars при компиляции для C не делает, а GCC не для C или C ++.