Почему мы не используем (void) в основном? - PullRequest
32 голосов
/ 01 июля 2010

Люди используют void main() /*empty parens ()*/

меня научили писать void main(void)

Есть идеи, в чем разница?

Ответы [ 5 ]

37 голосов
/ 01 июля 2010

Я не уверен, каковы стандарты в настоящее время, но в традиционном ANSI C использование пустых скобок означает, что функция может принимать любое количество аргументов. С другой стороны, объявление параметра void означает, что функция принимает только нулевые аргументы . В этом случае (и во многих других) это не имеет большого значения.

Если вы хотите быть строгим, лучше определить параметр void. Конечно, функция main также может быть определена как int main(int argc, const char* argv[]) - что совершенно правильно, но часто не нужно, если вам не нужны аргументы.

18 голосов
/ 01 июля 2010

Из стандарта C99:

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

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

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

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

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

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

Когда main определен без параметров, будут ли argc и argv все еще присутствовать в стеке?

5 голосов
/ 01 июля 2010

Эти прототипы main () являются нестандартными.

Точность по этому вопросу можно найти в файле comp.lang.c faq: http://c -faq.com / decl /main.html

РЕДАКТИРОВАТЬ : изменено «неправильно» на «нестандартное», поскольку норма допускает реализации прототипов, определенных реализацией.

2 голосов
/ 01 июля 2010

Разницы нет, но обычно main должен возвращать int.Некоторые компиляторы выдают предупреждение (по крайней мере, компилятор GNU - gcc):

$ cat x.c
void main(void){}

$ gcc x.c
x.c: In function `main':
x.c:1: warning: return type of 'main' is not `int'

Как уже упоминалось, прототип main (согласно стандарту):

int main(int argc, const char* argv[])

1 голос
/ 01 июля 2010

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 не использует их)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...