аварийное прекращение работы, оконечное или выход?

Каково различие между теми тремя, и как я закончу программу в случае исключения, которое я не могу обработать правильно?

103
задан There is nothing we can do 12 May 2010 в 15:28
поделиться

4 ответа

Я бы посоветовал не использовать ни один из них . Вместо этого перехватите исключения, которые вы не можете обработать в main (), и просто вернитесь оттуда. Это означает, что вам гарантировано, что раскрутка стека происходит правильно и вызываются все деструкторы. Другими словами:

int main() {
    try {
       // your stuff
    }
    catch( ... ) {
       return 1;    // or whatever
    }
}
5
ответ дан 24 November 2019 в 04:20
поделиться
  • terminate оставляет вам возможность зарегистрировать, что произойдет при его вызове. Должен быть один из двух других.
  • exit - это обычный выход, позволяющий указать статус выхода. Обработчики, зарегистрированные функцией at_exit (), запускаются
  • abort - это аварийный выход. Единственное, что запускается, - это обработчик сигнала для SIGABRT.
3
ответ дан 24 November 2019 в 04:20
поделиться
  • terminate() автоматически вызывается когда возникает исключение, которое невозможно не может быть обработано. По умолчанию terminate() вызывает abort(). Вы можете установить пользовательский с помощью функции set_terminate().

    abort() посылает сигнал SIGABRT.

    exit() не обязательно является плохим решением. не обязательно плохо. Она успешно завершает приложение и вызывает функцию atexit() функции в порядке LIFO. Я не обычно не вижу такого в приложениях на C++ приложениях, однако, я вижу это во многих приложениях на базе unix, где посылает код выхода в конце. Обычно exit(0) означает успешный запуск приложения.

4
ответ дан 24 November 2019 в 04:20
поделиться
  • abort указывает на "ненормальный" конец программы и вызывает сигнал POSIX SIGABRT, что означает, что любой обработчик, который вы зарегистрировали для этого signal будет вызван, хотя программа все равно завершит послесловие в любом случае. Обычно вы используете abort в программе на C, чтобы выйти из непредвиденного случая ошибки, когда ошибка, скорее всего, является ошибкой в ​​программе, а не чем-то вроде неправильного ввода или сбоя сети. Например, вы можете прервать , если будет обнаружено, что в структуре данных есть указатель NULL, хотя по логике этого никогда не должно происходить.

  • exit указывает на «нормальный» конец программы, хотя это все еще может указывать на сбой (но не на ошибку). Другими словами, вы можете выйти из с кодом ошибки, если пользователь ввел ввод, который не может быть проанализирован, или файл не может быть прочитан. Код выхода 0 указывает на успех. exit также необязательно вызывает обработчики перед завершением программы. Они регистрируются функциями atexit и on_exit .

  • std :: terminate - это то, что автоматически вызывается в программе C ++ при возникновении необработанного исключения. По сути, это эквивалент C ++ abort , предполагающий, что вы сообщаете обо всех своих исключительных ошибках посредством выдачи исключений. Это вызывает обработчик, установленный функцией std :: set_terminate , которая по умолчанию просто вызывает abort .

В C ++ обычно нужно избегать вызова abort или exit в случае ошибки, поскольку лучше генерировать исключение и позволять коду дальше по стеку вызовов решать, нужно ли или уместно не завершать программу. Независимо от того, используете ли вы exit для успеха, это вопрос обстоятельств - имеет ли смысл завершить программу где-нибудь, кроме оператора return в main .

std :: terminate следует рассматривать как последний инструмент сообщения об ошибках, даже в C ++.Проблема с std :: terminate заключается в том, что обработчик terminate не имеет доступ к исключению, которое осталось необработанным, поэтому нет способа определить, что это было. Обычно гораздо лучше обернуть весь main блоком try {} catch (std :: exception & ex) {} . По крайней мере, тогда вы можете сообщить больше информации об исключениях, происходящих из std :: exception (хотя, конечно, исключения, которые не происходят из std :: exception , все равно останутся необработанными).

Заключение тела main в try {} catch (...) {} не намного лучше, чем установка обработчика завершения, потому что снова у вас нет доступа к рассматриваемое исключение. Изменить: Ответ Нила Баттерворта, есть преимущество в том, что в этом случае стек раскручивается, что (несколько удивительно) неверно для необработанного исключения.

139
ответ дан 24 November 2019 в 04:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: