Правильно объявив функцию main() в ANSI C

Стандарт С говорит:

Функция, вызываемая при запуске программы, называется основной. Реализация не объявляет прототип для этой функции. Он должен быть определен с типом возврата int и без параметров:

int main(void) { /* ... */ }

или с двумя параметрами (именуемыми здесь как argc и argv, хотя могут использоваться любые имена, так как они являются локальными для функции, в которой они объявлены):

int main(int argc, char *argv[]) { /*
... */ }

или эквивалентный или каким-либо другим способом, определяемым реализацией.

Тем не менее, Kernighan & Ritchie в своей библии второго издания (канонического ANSI C) просто используют:

main()
{
  /* taram pampam ... */

  return 0;
}

Кто прав? Связано ли это с функцией без возвращаемого значения, автоматически предполагающей возвращение int в С?

4 ответа

Решение

Ну, если вы хотите ANSI C, то по определению стандарт является правильным.

В С89/ С90 int подразумевается тип возвращаемого значения, поэтому определение K&R будет приемлемым.

В С99 это уже не так.

Стандарт C90 имеет следующую формулировку (5.1.2.2.1 "Запуск программы"), которая очень похожа на формулировку C99 (вероятно, наиболее значительно он использует менее сильное "может" вместо "должен"):

Функция, вызываемая при запуске программы, называется main, Реализация не объявляет прототип для этой функции. Это может быть определено без параметров:

int main(void) { /* ... */ }

или с двумя параметрами (упоминается здесь как argc а также argvхотя могут использоваться любые имена, так как они являются локальными для функции, в которой они объявлены):

int main(int argc, char *argv[]) { /* ... */ }

Если они определены, параметры к main Функция должна подчиняться следующим ограничениям:

[так далее. ...]

В этом разделе нет ничего о том, что если вы не укажете тип возвращаемого значения, по умолчанию int,

Честно говоря, мне трудно найти, где именно это поведение указано в стандарте. Самое близкое, что я могу сделать, это 6.7.1 (Определения функций), где грамматика для определений функций указывает, что "спецификаторы объявлений" являются необязательными, а примеры говорят:

Примеры:

  1. В следующих:

      extern int max(int a, int b)
      {
          return a > b ? a : b;
      }
    

    extern спецификатор класса хранения и int является спецификатором типа (каждый из которых может быть опущен, так как это значения по умолчанию)...

Да, в C89 (исходный стандарт C), если функция объявлена ​​без возвращаемого типа, предполагается, что она возвращает int, C99 требует явного типа возврата для всех функций.

Кроме того, есть небольшая разница (по крайней мере, в объявлениях) между main() и main(void) -

main()

является функцией (неявно), возвращающей int и принимающей неопределенное количество аргументов

main(void)

не принимает аргументов

Версия K&R, которая была у меня, была напечатана в 1988 году. К тому времени Стандарт еще не вышел, поэтому есть некоторые несоответствия. Тем не менее, большая часть 2-го издания соответствует стандарту C89.

Я нашел текстовую версию C89 Standard (YAY для Google); это говорит:

"Запуск программы"

Функция, вызываемая при запуске программы, называется основной. Реализация не объявляет прототип для этой функции. Это может быть определено без параметров:

     int main(void) { /*...*/ }

или с двумя параметрами (именуемыми здесь как argc и argv, хотя могут использоваться любые имена, так как они являются локальными для функции, в которой они объявлены):

     int main(int argc, char *argv[]) { /*...*/ }
Другие вопросы по тегам