Ответ 5
main
является функцией, как и другая функция. Почти. В любом случае, будучи функцией, он вызывается каким-то другим кодом (стартовый код). Обычно (читайте: почти всегда) int main()
является правильным, но действительно, что истинно верно, зависит от платформы, в которой вы ее работаете. Поскольку, как сказано, основная функция может быть вызвана кодом запуска, который вообще не передает никаких аргументов и не ожидает возврата значения в конкретном регистре (так что void main(void)
является правильным).
int main()
является правильным, так как обычно запускается код, ожидающий возвращаемое значение, и передается два аргумента. Говоря int main(void)
, вы говорите, что main не принимает никаких аргументов вообще, это неверно в большинстве случаев. С ()
вы говорите, что есть аргументы (один, два, три, вам все равно), но вас это не интересует, поэтому вам не интересно говорить, что это такое и какой тип они есть.
Как я могу видеть в кодах, наиболее часто используемый прототип для "нормальных" сред (без встроенного устройства или других "странных" сред, где main можно вызывать по-разному) int main()
, когда вы игнорируете переданные аргументы int argc, char **argv
. (GCC жалуется, так как мы используем версию для gcc, подходящую для среды, протестируем ее с перекрестной версией GCC для одной из среды, где код запуска не передает никаких аргументов и не ожидает возврата)
изменить
Просто быть добрым к скептическим людям; в среде, где вызывается главная функция, с двумя аргументами, следующая
int func()
{
return 0;
}
int func2(void)
{
return 1;
}
int main(void)
{
int a;
a = func(a, a); /* A */
a = func2(a); /* B */
return 0;
}
не говорит об ошибке для A, а для B говорит too many arguments to function ‘func2’
, скомпилировано с gcc -std=c99 -pedantic
. Изменение int main(void)
на int main()
не имеет значения и никаких предупреждений.
В других средах (сейчас я не могу делать практические тесты), void main(void)
в порядке, в то время как в этом случае он вызывает предупреждение. Предупреждение не связано только с стандартом, но только потому, что в используемой среде прототип для основного не соответствует. Стандарт, по-видимому, допускает любую другую "конфигурацию" для основного.
В случае OP, рассматривая "нормальную" среду (например, GNU/Linux), где два аргумента передаются в основную часть, а ожидаемое значение ожидается, int main()
является предпочтительным (аргументы нажимаются стек по коду запуска, говорите ли вы int main(void)
или нет, поэтому int main()
для меня больше смысла)
изменить
Еще одно замечание, всегда для скептически настроенного человека. Как уже было доказано, B вызывает ошибку, так как я сказал, что это int func2(void)
, но я называю это передачей аргумента. Предположим, мы можем скомпилировать код запуска и связать его, как и любой другой код. Где-то он будет называть основной, таким образом, как
retval = main(argc, argv);
Если мы использовали int main(void)
, компилятор остановится, указав ошибку, поскольку код запуска (в этой среде) пытается вызвать main с двумя аргументами. Если мы используем int main()
, ничего не происходит, и код будет скомпилирован правильно.
Итак, int main()
превосходит до int main(void)
(в среде, где мы ожидаем, что возможны два аргумента)
изменить
Скорее всего, вызов похож на
retval = main(_argc, _argv, environ);
во многих системах, но это не меняет предыдущую речь.
окончательное редактирование
Кто-нибудь нашел, что при создании инструмента командной строки (т.е. в системах, где int argc, char **
имеет смысл) с int main(void)
, выбранный компилятор/компоновщик связывает код запуска, в котором main
вызывается без аргументов (независимо от того, вызывающие соглашения), а вместо этого при создании с помощью int main(int argc, char **argv)
код запуска отличается и фактически вызывает main
с этими двумя аргументами (даже если сам main
не использует их)?