Правильно объявив функцию 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 (Определения функций), где грамматика для определений функций указывает, что "спецификаторы объявлений" являются необязательными, а примеры говорят:
Примеры:
В следующих:
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[]) { /*...*/ }