Почему программы в C компилируются, даже если оператор возврата отсутствует?

Я внедряю некоторые базовые структуры данных в C, и я обнаружил, что если я опускаю возвращаемый тип из функции и вызываю эту функцию, компилятор не генерирует ошибку. Я скомпилировал с cc file.c и не использовал -Wall (поэтому я пропустил это предупреждение), но на других языках программирования это серьезная ошибка, и программа не будет компилироваться.

В запросе Per Graham Borland, вот простой пример:

int test() 
{
  printf("Hi!");
}

int main() 
{ 
    test();
}

Ответ 1

C является старым языком и в то время, когда он был введен, возвращаемые целые числа были достаточно распространены, чтобы быть возвращаемым по умолчанию типом функции. Затем люди начали понимать, что с более сложными типами возврата лучше всего указать int, чтобы убедиться, что вы не забываете тип возвращаемого значения, но чтобы поддерживать обратную совместимость со старым кодом, C не смог удалить это поведение по умолчанию. Вместо этого большинство компиляторов выдают предупреждения.

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

/* implicit declaration of printf as: int printf(int); */

/* implicit int type */
main()
{
    printf("hello, world\n");
} /* implicit return 0; */

Ответ 2

Это потому, что в C любая переменная/функция неявно int.

По той же причине вы можете использовать register вместо register int или unsigned вместо unsigned int, auto вместо auto int и static вместо static int. Я лично всегда четко определяю свои переменные с помощью int, но независимо от того, делаете вы это или нет, это ваш вариант.

Ответ 3

Возвращаемый тип функции является необязательным и считается "int", если не указан.

Ответ 4

Я пока не видел, почему в любом из ответов было сказано. В C это совершенно легально для функции с не-void возвращаемым типом для завершения без оператора return/value, если вызывающий объект не пытается использовать возвращаемое значение. Например (слегка нетривиальный пример):

#include <stdio.h>
int foo(int want_result)
{
    puts("hello");
    if (want_result) return 42;
}

int main()
{
    foo(0);
    printf("%d\n", foo(1));
}

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

Ответ 5

Функция не вернет 0, как сказано выше. Фактически printf возвращает значение: количество напечатанных символов. В вашем случае printf, который является последним выражением в вашей тестовой функции, вернет 3. Таким образом, функция test вернет 3.