Как среда выполнения C ++ определяет тип сгенерированного исключения? - PullRequest
8 голосов
/ 14 июня 2009

Если я сделаю следующее, как среда выполнения определяет тип сгенерированного исключения? Использует ли он RTTI для этого?

try
{
  dostuff(); // throws something
}
catch(int e)
{
  // ..
}
catch (const char * e)
{
  // ..
}
catch (const myexceptiontype * e)
{
  // ..
}
catch (myexceptiontype e) // is this the same as the previous handler?
{
  // ..
}

Смотри также:

Как реализована среда обработки исключений в C ++?

Ответы [ 2 ]

7 голосов
/ 14 июня 2009

В отличие от вопросов, заданных в этих других вопросах, ответ на этот вопрос может быть дан полностью посредством Стандарта. Вот правила

Обработчик соответствует объекту исключения типа E, если

  • Обработчик имеет тип cv T или cv T &, а E и T относятся к одному и тому же типу (игнорируя cv-квалификаторы верхнего уровня), или
  • обработчик имеет тип cv T или cv T &, а T является однозначным общедоступным базовым классом E, или
  • обработчик имеет тип cv1 T * cv2, а E является типом указателя, который может быть преобразован в тип обработчика одним или обоими
    • стандартное преобразование указателя (4.10), не включающее преобразование указателей в закрытые или защищенные или неоднозначные классы
    • Преобразование квалификации

[Примечание: выражение-бросок, являющееся целочисленным константным выражением целочисленного типа с нулевым значением не соответствует обработчику типа указателя; то есть преобразования констант нулевого указателя (4.10, 4.11) не применять. ]

Поскольку я не совсем уверен в вашем уровне понимания Стандарта, я оставлю это необъяснимым и отвечу, как вы попросите.

Что касается того, использует ли он RTTI или нет, то тип создаваемого объекта исключения - статический тип выражения , которое вы передаете в оператор throw (некоторое время назад мне было весело выяснить это в GCC). Так что не нужно делать идентификацию типа во время выполнения. Так что с g++ случается так, что на стороне, где появляется throw, он передает объект std::type_info, представляющий тип объекта исключения, сам объект и функцию деструктора.

Затем он генерируется и выполняется поиск кадров для соответствующего обработчика. Используя информацию, найденную в больших таблицах (расположенную в разделе с именем .eh_frame), и используя обратный адрес, он смотрит, какая функция отвечает за следующую обработку. Функция будет иметь установленную индивидуальную процедуру, которая выяснит, сможет ли она обработать исключение или нет. Вся эта процедура описана (и, конечно, более подробно) в ABI Itanium C ++ (реализованной в G ++), связанной с @PaV.

Итак, для вывода

myexceptiontype e

и

const myexceptiontype *e

Не обрабатывайте, конечно, того же типа.

4 голосов
/ 14 июня 2009

Спецификация для реализации отсутствует. Реализация должна следовать стандарту, и нет никаких ограничений на то, как это достигается. И существует более одной реализации, даже для одного компилятора.

Пример одной из таких реализаций вы можете прочитать здесь:

Itanium C ++ ABI: обработка исключений

...