try-block: try compound-statement handler-seq
function-try-block: try ctor-initializer compound-statement handler-seq
handler-seq: handler handler-seq
handler: catch ( exception-declaration ) compound-statement
exception-declaration: attribute-specifier-seq type-specifier-seq declarator attribute-specifier-seq type-specifier-seq abstract-declarator ...
void f() { goto l1; // error goto l2; // error try { goto l1; // OK goto l2; // error l1: ; } catch (...) { l2: ; goto l1; // error goto l2; // OK } }— end example
lab: try { T1 t1; try { T2 t2; if (condition) goto lab; } catch(...) { /* handler 2 */ } } catch(...) { /* handler 1 */ }
int f(int); class C { int i; double d; public: C(int, double); }; C::C(int ii, double id) try : i(f(ii)), d(id) { // constructor statements } catch (...) { // handles exceptions thrown from the ctor-initializer and from the constructor statements }— end example
throw "Help!";can be caught by a handler of const char* type:
try { // ... } catch(const char* p) { // handle character string exceptions here }and
class Overflow { public: Overflow(char,double,double); }; void f(double x) { throw Overflow('+',x,3.45e107); }can be caught by a handler for exceptions of type Overflow:
try { f(1.2); } catch(Overflow& oo) { // handle exceptions of type Overflow here }
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 ([class.copy.elision]) } catch(C) { } }— end example
struct A { }; struct Y { ~Y() noexcept(false) { throw 0; } }; A f() { try { A a; Y y; A b; return {}; // #1 } catch (...) { } return {}; // #2 }
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) { // ... } }
noexcept-specifier: noexcept ( constant-expression ) noexcept
struct B { virtual void f() noexcept; virtual void g(); virtual void h() noexcept = delete; }; struct D: B { void f(); // error void g() noexcept; // OK void h() = delete; // OK };
struct A { A(int = (A(5), 0)) noexcept; A(const A&) noexcept; A(A&&) noexcept; ~A(); }; struct B { B() noexcept; B(const B&) = default; // implicit exception specification is noexcept(true) B(B&&, int = (throw 42, 0)) noexcept; ~B() noexcept(false); }; int n = 7; struct D : public A, public B { int * p = new int[n]; // D::D() potentially-throwing, as the new operator may throw bad_alloc or bad_array_new_length // D::D(const D&) non-throwing // D::D(D&&) potentially-throwing, as the default argument for B's constructor may throw // D::~D() potentially-throwing };