В чем разница между этими тремя, и как мне закончить программу в случае исключения, которое я не могу обработать должным образом?прерывание, завершение или выход?
ответ
Мой совет - не использовать ни один из них. Вместо этого поймайте исключения, с которыми вы не можете справиться в main(), и просто возвращайтесь оттуда. Это означает, что вам гарантировано, что разворачивание стека происходит правильно и вызываются все деструкторы. Другими словами:
int main() {
try {
// your stuff
}
catch(...) {
return 1; // or whatever
}
}
Huh. Я должен был проверить это самостоятельно, но вы правы, что разматывание стека не обязательно происходит для неперехваченного исключения. Я нахожу это удивительным. –
Зачем это удивлять? –
@Neil: Согласовано в основном, но исключения, которые программа не может обрабатывать, должны сообщаться и обновляться. Пусть приложение рухнет. –
- terminate оставляет за собой возможность зарегистрировать, что произойдет, когда оно будет вызвано. Должен быть один из двух других.
- exit - это нормальный выход, позволяющий указать статус выхода. Обработчики, зарегистрированные с помощью at_exit(), запускаются
- abort - ненормальный выход. Единственное, что выполняется, это обработчик сигнала для SIGABRT.
аборт указывает «аномальный» конец к программе, и поднимает сигнал SIGABRT POSIX, а это значит, что любой обработчик, который вы зарегистрировали для этого сигнала будет вызван, хотя в любом случае программа будет по-прежнему прервать последующие слова. Обычно вы должны использовать
abort
в программе на C, чтобы выйти из непредвиденного случая ошибки, где ошибка, скорее всего, будет ошибкой в программе, а не что-то вроде плохого ввода или сбоя сети. Например, вы могли быabort
, если бы была найдена структура данных с указателем NULL, когда это должно логически никогда не происходить.exit указывает на «нормальный» конец программы, хотя это может по-прежнему указывать на сбой (но не на ошибку). Другими словами, вы можете
exit
с кодом ошибки, если пользователь дал ввод, который не мог быть проанализирован, или файл не мог быть прочитан. Код выхода 0 указывает на успех.exit
также дополнительно обрабатывает обработчики до того, как он закончит программу. Они регистрируются с помощью функцийatexit
иon_exit
.std :: terminate - это то, что автоматически вызывается в программе на C++, когда есть необработанное исключение. Это по существу эквивалент C++, равный
abort
, предполагая, что вы сообщаете обо всех своих исключительных ошибках с помощью исключения исключений. Это вызывает обработчик, который устанавливается функциейstd::set_terminate
, которая по умолчанию просто вызываетabort
.
В C++, обычно требуется, чтобы избежать вызова abort
или exit
об ошибке, так как вы лучше бросать исключение и дать код дальше стека вызовов решить или нет завершения программы является целесообразным. Независимо от того, используете ли вы exit
для успеха, это вопрос обстоятельств - имеет ли смысл закончить программу где-то, кроме оператора возврата, в main
.
std::terminate
следует рассматривать как средство отчетности об ошибках последнего времени, даже на C++. Проблема с std::terminate
заключается в том, что обработчик завершения имеет , а не, имеет доступ к исключению, которое прошло необработанным, поэтому нет способа сказать, что это было. Вы обычно намного лучше обертываете всю основную часть в блоке try { } catch (std::exception& ex) { }
.По крайней мере, вы можете сообщить дополнительную информацию об исключениях, которые получены из std::exception
(хотя, конечно, исключения, которые не происходят из std::exception
, все равно будут необработаны).
Обтекание тела main
в try { } catch(...) { }
не намного лучше, чем установка обработчика завершения, потому что снова у вас нет доступа к рассматриваемому исключению. Редактировать: Ответ Пер Нила Баттерворта, есть преимущество в том, что в этом случае стека раскручивается, что (несколько удивительно) неверно для необработанного исключения.
Можете ли вы обновить этот ответ с помощью C++ 11 info? Кажется, что теперь есть способы получить исключение в catch (...) и в обработчике terminate. – Klaim
В C++ обработчик terminate * имеет * доступ к исключению через 'std :: current_exception()'. См. Пример здесь: https://akrzemi1.wordpress.com/2011/10/05/using-stdterminate/ – anorm
Не имеет значения, что вы можете получить текущее исключение, так как вы не можете его проверить. Все, что вы можете сделать, это перебросить его. – seattlecpp
прекращается() автоматически вызывается , когда происходит исключение, которое не может быть обработано . По умолчанию terminate() вызывает abort(). Вы можете установить настраиваемый дескриптор с функцией set_terminate().
abort() посылает сигнал SIGABRT.
выход() не обязательно плохой вещь. Он успешно выходит из приложения и вызывает функции atexit() в порядке LIFO. Я не обычно вижу это в C++ приложениях, однако я вижу его в во многих приложениях на основе unix, где он отправляет код завершения в конце. Обычно выход (0) указывает на успешный запуск приложения .
Неудачный! Как в Unix, так и в DOS, exit (0) указывает на успех и любое другое значение, переданное exit() указывает на сбой, а не наоборот. –
-1 неудачно, не удалось – Petter
станд :: прервать и станд :: выход (и больше: станд :: _ Выход, станд :: quick_exit) только нижние функции уровня. Вы используете их, чтобы сообщить программе, что вы хотите, чтобы точно: какие деструкторы (и если) вызывать, какие другие функции очистки для вызова, какое значение нужно вернуть и т. Д.
std :: terminate is a абстракция более высокого уровня: она называется (либо временем выполнения, либо вами), чтобы указать, что произошла ошибка в программе, и по какой-то причине ее невозможно обработать, выбросив исключение. Необходимость в этом обычно возникает, когда ошибка возникает в самом механизме исключения, но вы можете использовать ее в любое время, когда вы не хотите, чтобы ваша программа продолжалась за пределами данной ошибки. Я собрал полный список ситуаций, когда std :: terminate называется in my post. Не указано, что делает std :: terminate, потому что вы контролируете его. Вы можете настроить поведение, зарегистрировав любые функции. Ограничения, которые у вас есть, это то, что функция не может вернуться на сайт ошибки и не может выйти из-за исключения, но технически вы даже можете запустить свой насос сообщений внутри. Список полезных вещей, которые вы можете сделать внутри, см. В разделе my other post.
В частности, обратите внимание, что std :: terminate считается обработчиком исключений в контекстах, где std :: terminate вызывается из-за вызванного исключения, которое невозможно обработать, и вы можете проверить, что такое исключение, и проверить его на используя C++ 11, используя std :: rethrow_exception и std :: current_exception. Это все в my post.
Если программа многопоточная, то вызов exit()
, скорее всего, приведет к аварии, поскольку глобальные/статические объекты std::thread
будет предпринята попытка уничтожить, не выходя их нитками.
Если вы хотите вернуть код ошибки и выйти из программы (более или менее), вызовите quick_exit()
в многопоточных программах. Для аномального завершения (без возможности указать код ошибки) можно назвать abort()
или std::terminate()
.
Примечание: quick_exit() has not been supported by MSVC++ до версии 2015 года.
спасибо! это действительно помогло мне! – sailfish009
- 1. Выход или прерывание?
- 2. Выход или завершение сеанса В Vaadin
- 3. Прерывание while() и завершение изящно Node.js
- 4. Выход/Завершение работы/приложения - андроид
- 5. Как проверить завершение сеанса или выход из системы в asp.net
- 6. Как прерывание/Стоп/Завершение висит многопоточную программу питона
- 7. Подпроцесс Python получает выход как завершение процесса
- 8. Завершение сеанса при нажатии Выход из системы
- 9. содержание выход или выход
- 10. Прерывание/прерывание VBA-Loop
- 11. Прерывание или остановка спальной нити
- 12. Остановка или прерывание Java-потока
- 13. C++ Прерывание или Отмена getch();
- 14. Реализовать удаление или завершение?
- 15. C++ 0x прерывание потока
- 16. выход/прерывание основной функции из вызываемой/дочерней функции
- 17. C#: внутренние работы: события, управление.BeginInvoke и выход программы = прерывание?
- 18. STM32F0 выход из STOP на прерывание приема SPI
- 19. BB10 Webworks упаковка Прерывание (прерывание)
- 20. Emacs завершение: автозаполнение или компания?
- 21. Завершение или удаление сеанса Asp.net
- 22. Добавление или принудительное прерывание строки после div
- 23. PHP - Прерывание или приостановка выполнения pthread
- 24. Golang: прекращение или прерывание HTTP-запроса
- 25. Прерывание, останов или таймаут Агент LotusScript внутри
- 26. Прерывание, метод отключения и ExecutorService
- 27. Выход или выход из игры в Andengine
- 28. UIBackgroundModes, выход на временный (или постоянный) выход
- 29. Завершение процесса, сохраненного SAS
- 30. Прерывание urllib.read
Это не дубликат, а скорее подмножество с хорошими ответами http://stackoverflow.com/questions/397075/what-is-the-difference-between-exit-and-abort и помечено как C++ слишком! –
'std :: abort' разумно, если исключение не может быть разрешено в деструкторе. – Daniel
Для получения дополнительной информации о 'std :: terminate' см. Эти статьи в отличном блоге C++ в Andrzej: https://akrzemi1.wordpress.com/2011/09/28/who-calls-stdterminate, https: //akrzemi1.wordpress. com/2011/10/05/using-stdterminate/ –