main
- это функция, как и другая функция. Почти. В любом случае, будучи функцией, она вызывается каким-то другим кодом (кодом запуска). Обычно (читай: почти всегда) int main()
является правильным, но действительно то, что является действительно правильным, зависит от платформы, на которой вы работаете. Поскольку, как уже было сказано, функция 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)
в порядке, в этом случае выдается предупреждение. Предупреждение не из-за одного стандарта, а только потому, что в используемой среде прототип для main не совпадает. Стандарт, кажется, допускает любую другую «конфигурацию» для main.
В случае 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)
(в среде, где мы ожидаем, что два аргумента для main возможны)
редактировать
Скорее всего, звонок похож на
retval = main(_argc, _argv, environ);
во многих системах, но это не меняет предыдущую речь.
окончательное редактирование
Кто-нибудь обнаружил, что при создании инструмента командной строки (то есть в системах, где int argc, char **
имеет смысл) с int main(void)
, выбранный компилятор / компоновщик связывает код запуска, где main
вызывается без аргументов (независимо от того, есть соглашения о вызовах), и вместо этого при сборке с int main(int argc, char **argv)
код запуска отличается и фактически вызывает main
с этими двумя аргументами (даже если сам main
не использует их)?