Тип возврата основной функции

Возможный дубликат:
Что должно вернуть main() в C/C++?
Разница между void main и int main?

Я всегда использовал основной метод в C, как

void main(){ // my code }

и это работает довольно хорошо для меня. Я тоже знаю о другом int тип возврата:

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

Но я не смог найти ни одного ресурса, который говорит, что я могу использовать void в качестве типа возврата. Каждая книга предполагает, что тип возвращаемого значения должен быть int или иначе это будет опущено. Тогда почему void main() Работа?

Это зависит от версии C, которую я использую? Или это работает, потому что я использую C++ IDE? Пожалуйста, ответьте конкретно на C, а не на C++.

5 ответов

Решение

Только авторы книг, кажется, знакомы с местом, где тип возврата void за main() позволено. Стандарт C++ запрещает это полностью.

Стандарт С говорит, что стандартные формы:

int main(void) { ... }

а также

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

разрешить альтернативные, но эквивалентные формы объявления для типов аргументов (и, конечно, имена являются полностью дискреционными, поскольку они являются локальными переменными для функции).

Стандарт C содержит небольшое условие для "в некоторой другой реализации, определенной способом". Стандарт ISO/IEC 9899:2011 гласит:

5.1.2.2.3 Завершение программы

Если тип возвращаемого значения main функция совместима с типом int, возврат от первоначального вызова к main Функция эквивалентна вызову exit функция со значением, возвращаемым main функция в качестве аргумента;11) достижение } которая завершает основную функцию, возвращает значение 0. Если возвращаемый тип не совместим с intстатус завершения, возвращаемый в хост-среду, не указан.

11) В соответствии с 6.2.4 время жизни объектов с автоматической продолжительностью хранения, объявленной в основном, закончится в первом случае, даже если в последнем случае их не будет.

Это явно позволяетint возвращает, но дает понять, что он не указан. Так, void может быть разрешено в качестве типа возврата main() какой-то реализацией, но вы можете найти это только в документации.

(Хотя я цитирую стандарт C2011, по сути те же слова были в C99, и я верю в C89, хотя мой текст для этого находится в офисе, а я нет.)

Кстати, в приложении J к стандарту упоминается:

J.5 Общие расширения

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

J.5.1 Аргументы среды

В размещенной среде main функция получает третий аргумент, char *envp[], что указывает на массив указателей с нулевым символом в конце charкаждая из которых указывает на строку, которая предоставляет информацию о среде для этого выполнения программы (5.1.2.2.1).

Почему void main() Работа?

Вопрос отмечает, что void main() работает. Это "работает", потому что компилятор делает все возможное, чтобы генерировать код для программ. Компиляторы, такие как GCC, будут предупреждать о нестандартных формах для main(), но обработаем их. Компоновщик не слишком беспокоится о типе возвращаемого значения; ему просто нужен символ main (или возможно _mainв зависимости от системы) и когда он находит его, связывает его в исполняемый файл. Код запуска предполагает, что main был определен стандартным образом. Если main() возвращается к коду запуска, он собирает возвращенное значение, как будто функция вернула int, но это значение, вероятно, будет мусором. Так что, похоже, это работает, пока вы не ищите статус выхода вашей программы.

Изо рта лошади:

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

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

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

    int main(int argc, char *argv[]) { /* ... */ }
или эквивалент;9) или каким-либо другим способом, определяемым реализацией.
9) Таким образом, int может быть заменено именем typedef, определенным как int, или тип argv может быть записан как char ** argv, и так далее.

Лазейка - это "какой-то другой способ, определенный реализацией". Реализация может позволить main возвращать void (или любой другой тип), но он должен явно задокументировать, что такая подпись разрешена. В противном случае поведение не определено, что означает, что компилятор может делать все, что захочет. Программа может выполняться без проблем. Может выполняться, но оставить среду в плохом состоянии. Может выйти из строя при выходе. Может вообще не загружаться.

Это зависит от используемого вами компилятора, но void main не везде компилируется. Я видел компиляторы, которые не будут компилировать программу с void main. Я не могу вспомнить конкретный случай (для c), но я точно знаю, что это происходит в g ​​++(да, я знаю, что это C++).

Стандартные призывы к main() возвращать int, но многие компиляторы Си позволяют вам указать тип возвращаемого значения main() как void,

Я рекомендую вам привыкнуть возвращаться int, Добавление

return 0;

до конца вашего main() не слишком много усилий.

Я был приемлем в C89, но это больше не считается "безопасным". Под C99 это больше не приемлемо.

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284376&answer=1044841143

Другие вопросы по тегам