18 Exception handling [except]

18.3 Handling an exception [except.handle]

В exception-declaration a handler описываются типы исключений, которые могут привести handler к его вводу. Не должен обозначать неполный тип, тип абстрактного класса или ссылочный тип rvalue. Не будет обозначать указатель или ссылку на неполный тип, кроме , , или .exception-declarationexception-declarationvoid*const void*volatile void*const volatile void*

Обработчик типа «массив T» или типа функции T настраивается на тип «указатель на T».

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

  • Имеет handlerтип cv T или cv T& и E и T относятся к тому же типу (без учета верхнего уровня cv-qualifiers), или

  • handlerимеет типа cv T или cv T& и T это однозначный общественные базовый класс E, или

  • handlerимеет тип , cv T или , const T& где T это указатель или указатель на тип члена и E представляет собой указатель или указатель на тип элемента , который может быть преобразован в T один или более из

  • handlerимеет тип , cv T или , const T& где T это указатель или указатель на тип члена и E является std​::​nullptr_­t.

[ Note: A throw-expression , операнд которого является целочисленным литералом со значением ноль, не соответствует обработчику указателя или указателя на тип члена. Обработчик ссылки на массив или тип функции никогда не соответствует какому-либо объекту исключения ([expr.throw]). ]end note

[Example:

class Matherr { /* ... */ virtual void vf(); };
class Overflow: public Matherr { /* ... */ };
class Underflow: public Matherr { /* ... */ };
class Zerodivide: public Matherr { /* ... */ };

void f() {
  try {
    g();
  } catch (Overflow oo) {
    // ...
  } catch (Matherr mm) {
    // ...
  }
}

Здесь Overflow обработчик перехватит исключения типа, Overflow а Matherr обработчик перехватит исключения типа Matherr и всех типов, которые являются общедоступными, Matherr включая исключения типа Underflow и Zerodivide. ]end example

Обработчики для блока try пробуются в порядке появления. [ Note: Это позволяет писать обработчики, которые никогда не могут быть выполнены, например, путем размещения обработчика для окончательного производного класса после обработчика для соответствующего однозначного общедоступного базового класса. ]end note

A ... в exception-declaration функциях обработчика аналогично ... объявлению параметра функции; он определяет совпадение для любого исключения. Если присутствует, ... обработчик должен быть последним обработчиком своего блока try.

Если среди обработчиков для блока try не найдено совпадений, поиск соответствующего обработчика продолжается в динамически окружающем блоке try того же потока.

Обработчик считается active завершенным после завершения инициализации параметра (если есть) в предложении catch. [ Note: В этот момент стек будет размотан. ] Кроме того, неявный обработчик считается активным, когда он вводится из-за выброса. Обработчик больше не считается активным после выхода из предложения catch.end notestd​::​terminate()

Исключение с последним активированным обработчиком, который все еще активен, называется currently handled exception.

Если соответствующий обработчик не найден,std​::​terminate() вызывается функция ; независимо от того, разматывается ли стек до того, как этот вызов std​::​terminate() определяется реализацией ([except.terminate]).

Обращение к любому нестатическому члену или базовому классу объекта в обработчике function-try-block конструктора или деструктора для этого объекта приводит к неопределенному поведению.

Область действия и время жизни параметров функции или конструктора распространяется на обработчики файла function-try-block.

Исключения , в деструкторах объектов со статической продолжительностью хранения или в конструкторах пространства имен область видимости объектов со статической продолжительностью хранения не пойманы function-try-block на main function. Исключения, возникающие в деструкторах объектов с длительностью хранения потока или в конструкторах объектов области пространства имен с длительностью хранения потока, не перехватываются a function-try-block в начальной функции потока.

Если оператор return появляется в обработчике function-try-block конструктора, программа имеет неправильный формат.

Текущее обработанное исключение генерируется повторно, если элемент управления достигает конца обработчика function-try-block конструктора или деструктора. В противном случае, истечение конца compound-statement a handler из a function-try-block эквивалентно истечению конца compound-statement этой функции (см. [stmt.return]).

Переменная, объявленная объектом exception-declarationтипа cv T или cv T&, инициализируется из объекта исключения типа Eследующим образом:

  • если T является базовым классом E, переменная происходит copy-initialized из соответствующего подобъекта базового класса объекта исключения;

  • в противном случае переменная берется copy-initialized из объекта исключения.

Время жизни переменной заканчивается, когда обработчик завершает работу, после уничтожения всех автоматических объектов, инициализированных в обработчике.

Когда обработчик объявляет объект, любые изменения этого объекта не влияют на объект исключения. Когда обработчик объявляет ссылку на объект, любые изменения в указанном объекте являются изменениями объекта исключения и вступят в силу, если этот объект будет повторно создан.