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

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

int main() 
{ 
    //... 
}

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

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

Ответ 1

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

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

Ответ 2

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

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

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

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

6.9.1/12

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

Вы можете проверить это с помощью 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

Ответ 3

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

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

Ответ 4

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

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