6 ответов:
мой совет был бы не использовать ни один из них. Вместо этого поймайте исключения, которые вы не можете обработать в main (), и просто вернитесь оттуда. Это означает, что вы гарантируете, что размотка стека происходит правильно и все деструкторы вызываются. Другими словами:
int main() { try { // your stuff } catch( ... ) { return 1; // or whatever } }
отмена указывает на "ненормальный" конец программы и вызывает сигнал POSIX SIGABRT, что означает, что любой обработчик, который вы зарегистрировали для этого сигнала, будет вызван, хотя программа все равно завершит послесловие в любом случае. Обычно вы бы использовали
abortв программе C для выхода из непредвиденного случая ошибки, когда ошибка, скорее всего, будет ошибкой в программе, а не чем-то вроде плохого ввода или сбоя сети. Для например, вы могли быabortЕсли в структуре данных был обнаружен нулевой указатель, когда это логически никогда не должно происходить.выход указывает на "нормальный" конец программы, хотя это все еще может означать сбой (но не ошибку). Другими словами, вы можете
exitС кодом ошибки, если пользователь дал сигнала, который не может быть обработан, или файл не может быть прочитан. Код выхода 0 указывает на успех.exitтакже вызовы обработчиков прежде чем он завершит программу. Они зарегистрированы вatexitиon_exitфункции.std:: terminate это то, что автоматически вызывается в программе C++, когда есть необработанное исключение. Это, по сути, в C++ эквивалентно
abort, предполагая, что вы сообщаете о всех своих исключительных ошибок с помощью исключений. Это вызывает обработчик, который устанавливаетсяstd::set_terminateфункция, которая по умолчанию просто вызываетabort.в C++ вы обычно хотите избежать вызова
abortилиexitпри ошибке, так как вам лучше выбросить исключение и позволить коду дальше вверх по стеку вызовов решить, подходит ли завершение программы. Независимо от того, используете ли выexitдля успеха это вопрос обстоятельств - имеет ли смысл заканчивать программу где-то еще, кроме оператора return вmain.
std::terminateследует считать a последние отчеты об ошибках инструмента, даже в C++. Проблема сstd::terminateэто то, что обработчик завершения делает не есть доступ к исключению, которое прошло без обработки, так что нет никакого способа сказать, что это было. Обычно вам гораздо лучше обернуть всю основную часть вtry { } catch (std::exception& ex) { }блок. По крайней мере, тогда вы можете сообщить дополнительную информацию об исключениях, полученных изstd::exception(хотя конечно исключения, которые не вытекают изstd::exceptionвсе равно останется необработанным).обертывание тела
mainнаtry { } catch(...) { }не намного лучше, чем установка обработчика завершения, потому что снова у вас нет доступа к рассматриваемому исключению. Edit: согласно ответу Нила Баттерворта, есть преимущество в том, что стек разматывается в этом случае, что (несколько удивительно) неверно для необработанного исключения.
std::abort и std:: exit (и еще:std::_Exit, std:: quick_exit) - это просто функции более низкого уровня. Вы используете их, чтобы сказать программе, что именно вы хотите, чтобы она делала: какие деструкторы (и если) вызывать, какие другие функции очистки вызывать, какое значение возвращать и т. д.
std:: terminate-это абстракция более высокого уровня: она вызывается (либо во время выполнения, либо вами), чтобы указать, что произошла ошибка в программе и что по какой-то причине ее невозможно обработать, бросив исключение. Необходимость в этом обычно возникает, когда ошибка возникает в самом механизме исключения, но вы можете использовать его в любое время, когда вы не хотите, чтобы ваша программа продолжалась после данной ошибки. Я составил полный список ситуаций, когда std::terminate называется в моем посте. Не указано, что делает std::terminate, потому что вы контролируете его. Вы можете настроить поведение, зарегистрировав любые функции. Ограничения у вас есть, что функция не может вернитесь обратно на сайт ошибки, и он не может выйти через исключение, но технически вы даже можете запустить свой насос сообщений внутри. Список полезных вещей, которые вы можете сделать внутри, см. мой пост.
в частности, обратите внимание, что std::terminate считается обработчиком исключений в контекстах, где std:: terminate вызывается из-за брошенного исключения, которое не может быть обработано, и вы можете проверить, что такое исключение, и проверить его с помощью C++11 с помощью std::rethrow_exception и std:: current_exception. Это все в мой пост.
если ваша программа многопоточна, то вызов
exit()скорее всего, приведет к аварии, потому что global / staticstd::threadобъекты будут пытаться уничтожить, не выходя из своих потоков.если вы хотите вернуть код ошибки и выход из программы (более или менее), как правило, называют
quick_exit()в многопоточных программах. Для аварийного завершения (без возможности указать код ошибки),abort()илиstd::terminate()можно назвать.Примечание: quick_exit () не поддерживается MSVC++ до версии 2015 .
terminate () вызывается автоматически когда возникает исключение, которое не может быть обработанным. По умолчанию завершить() вызывает abort(). Вы можете установить пользовательский ручка с set_terminate() функция.
abort () посылает сигнал SIGABRT.
exit() не обязательно плохо вещь. Он успешно завершает работу приложений и вызовы atexit() функции в порядке ЛИФО. Я не обычно это видно в C++ приложения, однако, я вижу это в многие unix на основе приложения, где это отправляет код выхода в конце. Обычно выход(0) указывает на успешный запуск приложения.
- terminate оставляет вам возможность зарегистрировать то, что произойдет, когда он будет вызван. Должен быть один из двух других.
- exit-это обычный выход, позволяющий задать статус выхода. Обработчики, зарегистрированные at_exit () выполняются
- аборт-это аварийный выход. Единственное, что выполняется-это обработчик сигнала для SIGABRT.
Comments