2013-07-24 3 views
7

Я читаю «Язык программирования C++ 4-е издание» Книга и есть вопрос, касающийся пункта о обработки исключений:Бросив исключение при обработке исключения

Есть случаи, когда обработка исключений должна быть заброшена меньше тонкие методы обработки ошибок. Руководящими принципами являются:

  • Не бросайте исключение при обработке исключения.
  • Не бросайте исключение, которое невозможно поймать.

Если реализация обработки исключений поймает вас, то она завершит вашу программу.

Может ли кто-нибудь дать мне пример первого ситутации? Только что-то подобное приходит мне на ум, но это действительный код в соответствии с g ++:

try 
{ 
    throw 1; 
} 
catch(...) 
{ 
    try 
    { 
     throw 2; 
    } 
    catch(...) 
    { 
     cout << "OK"; 
    } 
} 
+2

Не думайте, что что-то является действительным, и/или делает то, что вы думаете, только потому, что она составлена! 'C++' имеет концепцию [* undefined behavior *] (http://blog.regehr.org/archives/213), которая примерно переводится как «если вы делаете что-то недействительное, все ставки отключены». Он может упасть, он может работать, он может работать, но отправляет все номера вашей кредитной карты нигерийским князьям. Заметьте, я не говорю, что этот конкретный случай (я думаю, что это не UB, просто опасно близко), но не думаю, что «он скомпилирован, это нормально». – BoBTFish

+3

Я не могу согласиться с первым из них, но могу от души согласиться со вторым. Есть * много * раз catch-блоки могут генерировать исключения, включая одно и то же исключение (через 'throw;'). – WhozCraig

ответ

12

Это немного вводит в заблуждение; это прекрасно, чтобы выбросить из обработчика исключений (что я понял бы при обработке исключения »), если есть другой обработчик, чтобы его поймать.

Проблема в том, что вы выбрали исключение из деструктора объекта, который уничтожается во время разматывания стека. В этом случае есть два необработанных исключения, и обычный механизм исключения может иметь дело только с одним; поэтому ответ должен называться terminate.

Пример:

struct dodgy {~dodgy() {throw "Don't do this!";}}; 

try { 
    dodgy d; 
    throw 1; 
} catch (...) { 
    // Never reached: destroying `d` killed the program. 
} 
+0

+1 для определения поведения деструктора в среде с несколькими выбросами. Не часто рассматривается, но часто проблема. Хорошая запись. – WhozCraig

+0

Спасибо, я также нашел гораздо более подробное объяснение в стандарте - это 15.5.1/1. – Quentin

+0

Вы можете использовать 'std :: uncaught_exception', чтобы увидеть, может ли исключение бросать исключение. –