Почему возврат 0 необязателен?

Почему, если я пишу

int main() { //... } 

мне не нужно писать return 0; в конце main функции? Компилятор делает это для меня?

Я использую GCC / C99.

Самый последний C (в настоящее время это C99 с несколькими поправками) возвращает 0 из main по умолчанию, если в конце функции нет явного оператора return, а управление течет с конца функции (см. 5.1.2.2.3 в C99 TC3 ). Это потому, что чаще всего можно было бы написать такую ​​форму возврата в любом случае.

В C89 вам нужно что-то вернуть – у него нет такого неявного возврата. Но компилятор отнюдь не обязан диагностировать такую ​​ошибку (см. 3.6.6.4 в проекте C89 и 6.9.1 / 12 в C99 TC3 ).

C99 и C ++ особый случай, main функция возвращает 0, если управление достигает конца без явного возврата. Это относится только к main функции.

Соответствующий бит спецификации C99 – это 5.1.2.2.3 для main специального случая

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

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

6.9.1 / 12

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

Вы можете проверить это с помощью gcc:

 int foo ( void ) { } int main( void ) { } 

Режим C89 (ошибки для обеих функций):

 sandiego:$ gcc src/no_return.c -std=c89 -Wall src/no_return.c: In function 'main': src/no_return.c:2: warning: control reaches end of non-void function src/no_return.c: In function 'foo': src/no_return.c:1: warning: control reaches end of non-void function 

Режим C99 (основной – особый случай):

 sandiego:$ gcc src/no_return.c -std=c99 -Wall src/no_return.c: In function 'foo': src/no_return.c:1: warning: control reaches end of non-void function 

Да. main в C – это особая функция, которая содержит некоторые дополнительные правила. См. Параграф в стандарте C99 о его окончании ниже. По сути, он говорит, что если вы выходите из функции, не возвращая значения, это эквивалентно, как если бы вы дали возвращаемое значение 0 . Это особенно main , делая это с другими функциями, в которых вызывающая функция ожидает, что возвращаемое значение может (и будет) разбивать вашу программу.

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

В принципе, да. Функции не обязаны возвращать что-либо, даже если они объявляют тип возврата, отличный от void . Возвращаемое значение не будет определено.

Обратите внимание, что C99 требует, чтобы функции, объявляющие void возвращаемые типы, всегда заканчивались нажатием оператора return. Поэтому, если вы компилируете с использованием режима C99 вашего компилятора, этот код приведет к ошибке времени компиляции.

  • Поймать Ctrl-C в C
  • Правильный способ передачи 2-мерного массива в функцию
  • Как преобразовать целое число в шестнадцатеричную строку в C?
  • Что означает void * и как его использовать?
  • Эта программа звучит колокол!
  • Является ли модификация строковых литералов неопределенным поведением в соответствии со стандартом C89?
  • О примерном определении
  • Как отключить буферизацию stdout в C
  • Представление целых чисел в двухместных
  • Как я могу написать общий class контейнера, который реализует данный интерфейс в C #?
  • Проблема с поплавком на C
  • Давайте будем гением компьютера.