Однажды мне посоветовали, что программа на C ++ должна в конечном итоге перехватывать все исключения. В то время аргументация сводилась к тому, что программы, допускающие появление исключений за пределами, main()
переходят в странное состояние зомби. Мне сказали об этом несколько лет назад, и в ретроспективе я считаю, что наблюдаемое явление было связано с длительным созданием исключительно больших дампов ядра из рассматриваемого проекта.
В то время это казалось странным, но убедительным. Было совершенно бессмысленно, что C ++ должен «наказать» программистов за то, что они не перехватили все исключения, но доказательства, которые были до меня, похоже, подтверждали это. Для рассматриваемого проекта программы, которые выдавали неисследованные исключения, действительно входили в странное состояние зомби - или, как я подозреваю, причина была в том, что процесс посреди нежелательного дампа ядра необычайно трудно остановить.
(Для тех, кто интересуется, почему это не было более очевидным в то время: проект генерировал большое количество выходных данных в нескольких файлах из нескольких процессов, которые эффективно скрывали любые aborted (core dumped)
сообщения, и в этом конкретном случае посмертная проверка дампов ядра не была не является важной техникой отладки, поэтому дампы ядра не были особо продуманы. Проблемы с программой обычно не зависели от состояния, накопленного во многих событиях с течением времени долгоживущей программой, а скорее исходных входных данных для недолговечной программы (< 1 час), поэтому было практичнее просто перезапустить программу с теми же входными данными из отладочной сборки или в отладчике, чтобы получить больше информации.)
В настоящее время я не уверен в том, есть ли какое-либо существенное преимущество или недостаток в вылове исключений исключительно с целью предотвращения выхода исключений main()
.
Небольшое преимущество, которое я могу придумать, позволяя исключениям возникать в прошлом, main()
заключается в том, что это приводит к тому, что результат std::exception::what()
выводится на терминал (по крайней мере, для программ, скомпилированных gcc в Linux). С другой стороны, это тривиально, если вместо этого перехватить все исключения, полученные из, std::exception
и распечатать результат, std::exception::what()
и если желательно напечатать сообщение из исключения, которое не является производным, std::exception
оно должно быть перехвачено перед отправкой main()
, чтобы напечатать сообщение.
Скромный недостаток, который я могу придумать для того, чтобы разрешить возникновение исключений, main()
заключается в том, что могут генерироваться нежелательные дампы ядра. Для процесса, использующего большой объем памяти, это может быть довольно неприятно, и для управления поведением дампов ядра из программы требуются вызовы функций для конкретной ОС. С другой стороны, если желательны дамп ядра и выход, тогда вместо этого это может быть достигнуто в любое время с помощью вызова, std::abort()
а выход без дампа ядра может быть достигнут в любое время с помощью вызова std::exit()
.
Кстати, я не думаю, что когда-либо видел what(): ...
сообщение по умолчанию, распечатанное широко распространенной программой после сбоя.
Что, если таковые имеются, являются сильными аргументами за или против того, чтобы исключения C ++ всплыли в прошлом main()
?
Изменить: на этом сайте есть много общих вопросов обработки исключений. Мой вопрос касается, в частности, исключений C ++, которые не могут быть обработаны и дошли до них main()
- возможно, может быть напечатано сообщение об ошибке, но это ошибка немедленного показа остановки.