return statement vs exit () в main ()

Должен ли я использовать exit() или просто return утверждения в main() ? Лично я выступаю за заявления о return потому что я чувствую, что это как чтение любой другой функции, а управление streamом, когда я читаю код, является гладким (на мой взгляд). И даже если я хочу реорганизовать функцию main() , return будет лучшим выбором, чем exit() .

Вызывает ли exit() что-нибудь особенное, чего нет?

На самом деле, есть разница, но она тонкая. Это имеет большее значение для C ++, но различия важны.

Когда я вызываю return в main() , деструкторы будут вызваны для моих локально локализованных объектов. Если я вызову exit() , никакой деструктор не будет вызван для моих локально локализованных объектов! Перечитайте это. exit() не возвращается . Это означает, что, как только я это называю, «нет спиннинга». Любые объекты, созданные вами в этой функции, не будут уничтожены. Часто это не имеет никакого значения, но иногда это происходит, например, закрытие файлов (конечно, вы хотите, чтобы все ваши данные были сброшены на диск?).

Обратите внимание, что static объекты будут очищены, даже если вы вызовете exit() . Наконец, обратите внимание, что если вы используете abort() , никакие объекты не будут уничтожены. То есть глобальные объекты, статические объекты и локальные объекты не будут вызваны их деструкторами.

Соблюдайте осторожность, предпочитая выход за возврат.

http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a

Другое отличие: exit – это функция стандартной библиотеки, поэтому вам нужно включить заголовки и ссылку со стандартной библиотекой. Чтобы проиллюстрировать (на C ++), это действительная программа:

 int main() { return 0; } 

но для использования exit вам понадобится включить:

 #include  int main() { exit(EXIT_SUCCESS); } 

Плюс это добавляет дополнительное предположение: вызов вызова из main имеет те же побочные эффекты, что и возврат нуля. Как указывали другие, это зависит от того, какой исполняемый файл вы создаете (т. Е. Кто называет main ). Вы кодируете приложение, использующее C-runtime? Плагин майя? Служба Windows? Водитель? Для каждого случая потребуется исследование, чтобы проверить, соответствует ли exit эквиваленту return . ИМХО, использующий exit когда вы действительно подразумеваете return просто делает код более запутанным. OTOH, если вы действительно имеете в виду exit , тогда обязательно используйте его.

По крайней мере, одна из причин предпочтительного exit : если какой-либо из ваших обработчиков atexit ссылается на данные о продолжительности хранения данных в main , или если вы использовали setvbuf или setbuf для назначения одному из стандартных streamов буфера с продолжительностью хранения в хранилище main , то возврат из main вызывает неопределенное поведение, но вызов exit действителен.

Другим потенциальным использованием (обычно для программ игрушек) является выход из программы с рекурсивными вызовами main .

Я всегда использую return потому что стандартный прототип для main() говорит, что он возвращает int .

Тем не менее, некоторые версии стандартов дают main специальное обращение и предполагают, что он возвращает 0, если нет явного оператора return . Учитывая следующий код:

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

G ++ генерирует предупреждение только для foo() и игнорирует недостающее возrotation из main :

 % g++ -Wall -c foo.cc foo.cc: In function 'int foo()': foo.cc:1: warning: control reaches end of non-void function 

Я СИЛЬНО второй комментарий Р. об использовании exit (), чтобы избежать автоматического сохранения в main() возвращенного до того, как программа действительно закончится. return X; утверждение в main() не является точно эквивалентным вызову exit(X); , так как динамическое хранилище main() исчезает при возврате main() , но оно не исчезает, если вместо этого выполняется вызов exit() .

Кроме того, в C или любом C-подобном языке оператор return сильно намекает читателю, что выполнение будет продолжаться в вызывающей функции, и хотя это продолжение выполнения обычно технически истинно, если вы считаете процедуру запуска C, которая вызвала ваш main() функция, это не совсем то, что вы имеете в виду, когда вы хотите закончить процесс.

В конце концов, если вы хотите закончить свою программу из любой другой функции, кроме main() вы должны вызвать exit() . Выполнение этой последовательности в main() также делает ваш код более читабельным, а также значительно упрощает преобразование вашего кода; т.е. код, скопированный из main() в какую-либо другую функцию, не будет ошибочным из-за случайных операторов return которые должны были быть exit() .

Итак, объединяя все эти моменты вместе, вывод заключается в том, что это плохая привычка , по крайней мере для C, использовать оператор return для завершения программы в main() .

Вызывает ли exit () что-то особенное, что «return» не делает?

С некоторыми компиляторами для необычных платформ функция exit() может перевести свой аргумент в значение выхода вашей программы, а возврат из main() может просто передать значение непосредственно в среду хоста без какого-либо перевода.

Стандарт требует идентичного поведения в этих случаях (в частности, он говорит, что возrotation того, что является int -compatible from main() должно быть эквивалентно вызову exit() с этим значением). Проблема в том, что разные ОС имеют разные соглашения для интерпретации значений выхода. На многих (МНОГО!) Системах 0 означает успех, а что-то еще – провал. Но, скажем, VMS, нечетные значения означают успех и даже означают отказ. Если вы вернули 0 из main() , пользователь VMS увидел бы неприятное сообщение о нарушении доступа. На самом деле не было прав доступа – это было просто стандартное сообщение, связанное с кодом ошибки 0.

Затем ANSI пришел и благословил EXIT_SUCCESS и EXIT_FAILURE качестве аргументов, которые вы могли бы передать exit() . В стандарте также говорится, что exit(0) должен вести себя одинаково с exit(EXIT_SUCCESS) , поэтому большинство реализаций определяют EXIT_SUCCESS 0 .

Таким образом, стандарт ставит вас в привязку к VMS, поскольку он не оставляет стандартного способа возврата кода сбоя, который имеет значение 0.

В начале 1990-х годов разработчик VAX / VMS C компилятор не интерпретировал возвращаемое значение из main() , он просто возвращал любое значение в среду хоста. Но если вы использовали exit() он выполнил бы то, что требовалось стандартное: перевести EXIT_SUCCESS (или 0 ) в код успеха и EXIT_FAILURE в общий код отказа. Чтобы использовать EXIT_SUCCESS , вам нужно было передать его на exit() , вы не смогли бы вернуть его из main() . Я не знаю, сохранили ли более современные версии этого компилятора такое поведение.

Портативная программа на C, которая выглядит так:

 #include  #include  int main() { printf("Hello, World!\n"); exit(EXIT_SUCCESS); /* to get good return value to OS */ /*NOTREACHED*/ /* to silence lint warning */ return 0; /* to silence compiler warning */ } 

Кроме того: если я правильно помню, соглашение VMS для значений выхода более тонкое, чем нечетное / четное. На самом деле он использует что-то вроде низких трех бит для кодирования уровня серьезности. Вообще говоря, однако, нечетные уровни серьезности указывали на успех или разную информацию, а четные – на ошибки.

Interesting Posts

В запрошенном ресурсе нет заголовка «Access-Control-Allow-Origin» – при попытке получить данные из REST API

Будет ли чистая установка Windows 8 распознать лицензионный ключ / ключ продукта OEM?

Android Alternate row Colors в ListView

Заказ параметров для использования каррирования

При использовании макросов VM с VMWare, как использовать ключ командной строки в VM?

Можно ли показывать индикатор выполнения при загрузке изображения через Retrofit 2

angularjs не может найти каталог шаблонов, колбу в качестве бэкэнд

Как получить значение offset (). Верхнее значение элемента без использования jQuery?

java получить размер файла эффективно

Объединить два текстовых файла по строкам, используя командный скрипт

JPG to PDF Convertor в C #

Как вызвать веб-службу из jQuery

Время эпохи Unix для объекта Java Date

Twitter Bootstrap – как центрировать элементы по горизонтали или по вертикали

Эмулятор Android не может запускаться, из-за неправильной папки

Давайте будем гением компьютера.