18 Exception handling [except]

18.1 Throwing an exception [except.throw]

Создание исключения передает управление обработчику. [ Note: Исключение может быть выброшено из одного из следующих контекстов: throw-expressions, allocation functions, dynamic_­cast, typeid, new-expressions, и стандартные библиотечные функции ([structure.specifications]). ] Объект передается, и тип этого объекта определяет, какие обработчики могут его перехватить. [end noteExample:

throw "Help!";

может быть захвачено handler из const char* типа:

try {
    // ...
} catch(const char* p) {
    // handle character string exceptions here
}

а также

class Overflow {
public:
    Overflow(char,double,double);
};

void f(double x) {
    throw Overflow('+',x,3.45e107);
}

может быть перехвачен обработчиком исключений типа Overflow:

try {
    f(1.2);
} catch(Overflow& oo) {
    // handle exceptions of type Overflow here
}

end example]

Когда генерируется исключение, управление передается ближайшему обработчику с подходящим типом ([except.handle]); «Ближайший» означает обработчик, для которого ключевое слово compound-statementили ctor-initializer следующее за tryключевым словом было самым последним введено потоком управления и еще не завершено.

Создание исключения инициализирует копирование-инициализацию ([dcl.init], [class.copy]) временного объекта, называемого exception object. Значение lvalue, обозначающее временное, используется для инициализации переменной, объявленной в match handler([except.handle]). Если тип объекта исключения будет неполным типом или указатель на неполный тип, отличный cv void от программы, сформирован неправильно.

Память для объекта исключения распределяется неопределенным образом, за исключением случаев, указанных в [basic.stc.dynamic.allocation]. Если обработчик завершает работу путем повторной генерации, управление передается другому обработчику для того же объекта исключения. Точки потенциального разрушения объекта исключения:

  • когда активный обработчик исключения завершает работу любым способом, кроме повторной генерации, сразу после уничтожения объекта (если есть), объявленного exception-declarationв обработчике;

  • когда объект типа, std​::​exception_­ptr который ссылается на объект исключения, уничтожается до того, как деструктор std​::​exception_­ptr возвращает.

Среди всех точек потенциального разрушения для объекта исключения есть неуказанная последняя, ​​в которой уничтожается объект исключения. Все остальные пункты, happen before которые последний. [ Note: Никакая другая синхронизация потоков не подразумевается при обработке исключений. ] Затем реализация может освободить память для объекта исключения; любое такое освобождение выполняется неуказанным образом. [ Выброшенное исключение не распространяется на другие потоки, если оно не будет поймано, сохранено и повторно создано с использованием соответствующих библиотечных функций; видеть и . ]end noteNote: [propagation] [futures] end note

Когда брошенный объект является объектом класса, конструктор, выбранный для инициализации копирования, а также конструктор, выбранный для инициализации копирования, учитывая, что брошенный объект является lvalue, не должны быть удалены и доступны, даже если операция копирования / перемещения есть elided. Деструктор есть potentially invoked.

Исключение считается пойманным, когда его обработчик становится active. [ Note: Исключение может иметь активные обработчики и по-прежнему считаться неперехваченным, если оно генерируется повторно. ]end note

Если механизм обработки исключений, обрабатывающий объект, uncaught exception напрямую вызывает функцию, которая завершается через исключение, std​::​terminate вызывается. [Example:

struct C {
  C() { }
  C(const C&) {
    if (std::uncaught_exceptions()) {
      throw 0;      // throw during copy to handler's exception-declaration object ([except.handle])
    }
  }
};

int main() {
  try {
    throw C();      // calls std​::​terminate() if construction of the handler's
                    // exception-declaration object is not elided
  } catch(C) { }
}

end example] [ Note: Следовательно, деструкторы обычно должны перехватывать исключения и не позволять им распространяться. ]end note