Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Dynamic exception specification(until C++17)

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Exceptions
      try block
      Throwing exceptions
      Handling exceptions
      Exception specification
          noexcept specification(C++11)
          dynamic specification(until C++17*)
      noexcept operator(C++11)
       

      Lists the exceptions that a function might directly or indirectly throw.

      Contents

      [edit]Syntax

      throw(type-id-list (optional)) (1)(deprecated in C++11)
      (removed in C++17)
      1) Explicit dynamic exception specification.
      type-id-list - comma-separated list oftype-ids, a type-id representing apack expansion is followed by an ellipsis (...)(since C++11)

      An explicit dynamic exception specification shall appear only on a function declarator for a function type, pointer to function type, reference to function type, or pointer to member function type that is the top-level type of a declaration or definition, or on such a type appearing as a parameter or return type in a function declarator.

      void f()throw(int);// OK: function declarationvoid(*pf)()throw(int);// OK: pointer to function declarationvoid g(void pfa()throw(int));// OK: pointer to function parameter declarationtypedefint(*pf)()throw(int);// Error: typedef declaration

      [edit]Explanation

      If a function is declared with typeT listed in its dynamic exception specification, the function may throw exceptions of that type or a type derived from it.

      Incomplete types, pointers or references to incomplete types other than cvvoid*, and rvalue reference types(since C++11) are not allowed in the exception specification. Array and function types, if used, are adjusted to corresponding pointer types, top level cv-qualifications are also dropped.parameter packs are allowed(since C++11).

      A dynamic exception specification whose set of adjusted types is empty(after any packs are expanded)(since C++11) is non-throwing. A function with a non-throwing dynamic exception specification does not allow any exceptions.

      A dynamic exception specification is not considered part of a function’s type.

      If the function throws an exception of the type not listed in its exception specification, the functionstd::unexpected is called. The default function callsstd::terminate, but it may be replaced by a user-provided function (viastd::set_unexpected) which may callstd::terminate or throw an exception. If the exception thrown fromstd::unexpected is accepted by the exception specification, stack unwinding continues as usual. If it isn't, butstd::bad_exception is allowed by the exception specification,std::bad_exception is thrown. Otherwise,std::terminate is called.

      [edit]Instantiation

      The dynamic exception specification of a function template specialization is not instantiated along with the function declaration; it is instantiated only whenneeded (as defined below).

      The dynamic exception specification of an implicitly-declared special member function is also evaluated only when needed (in particular, implicit declaration of a member function of a derived class does not require the exception-specification of a base member function to be instantiated).

      When the dynamic exception specification of a function template specialization isneeded, but has not yet been instantiated, the dependent names are looked up and any templates used in theexpression are instantiated as if for the declaration of the specialization.

      A dynamic exception specification of a function is considered to beneeded in the following contexts:

      • in an expression, where the function is selected by overload resolution
      • the function isodr-used
      • the function would be odr-used but appears in an unevaluated operand
      template<class T>T f()throw(std::array<char, sizeof(T)>); int main(){    decltype(f<void>())*p;// f unevaluated, but exception specification is needed// error because instantiation of the exception specification// calculates sizeof(void)}
      • the specification is needed to compare to another function declaration (e.g. on a virtual function overrider or on an explicit specialization of a function template)
      • in a function definition
      • the specification is needed because a defaulted special member function needs to check it in order to decide its own exception specification (this takes place only when the specification of the defaulted special member function is, itself, needed).

      [edit]Potential exceptions

      Each functionf, pointer to functionpf, and pointer to member functionpmf has aset of potential exceptions, which consists of types that might be thrown. Set of all types indicates that any exception may be thrown. This set is defined as follows:

      1) If the declaration off,pf, orpmf uses a dynamic exception specification that does not allow all exceptions(until C++11), the set consists of the types listed in that specification.
      2) Otherwise, if the declaration off,pf, orpmf usesnoexcept(true), the set is empty.
      (since C++11)
      3) Otherwise, the set is the set of all types.

      Note: for implicitly-declared special member functions (constructors, assignment operators, and destructors) and for the inheriting constructors(since C++11), the set of potential exceptions is a combination of the sets of the potential exceptions of everything they would call: constructors/assignment operators/destructors of non-variant non-static data members, direct bases, and, where appropriate, virtual bases (including default argument expressions, as always).

      Each expressione has aset of potential exceptions. The set is empty ife is acore constant expression, otherwise, it is the union of the sets of potential exceptions of all immediate subexpressions ofe (includingdefault argument expressions), combined with another set that depends on the form ofe, as follows:

      1) Ife is a function call expression, letg denote the function, function pointer, or pointer to member function that is that is called, then
      • if the declaration ofg uses a dynamic exception specification, the set of potential exceptions ofg is added to the set;
      (since C++11)
      • otherwise, the set is the set of all types.
      2) Ife calls a function implicitly (it's an operator expression and the operator is overloaded, it is anew-expression and the allocation function is overloaded, or it is a full expression and the destructor of a temporary is called), then the set is the set of that function.
      3) Ife is athrow-expression, the set is the exception that would be initialized by its operand, or the set of all types for the re-throwing throw-expression (with no operand).
      4) Ife is adynamic_cast to a reference to a polymorphic type, the set consists ofstd::bad_cast.
      5) Ife is atypeid applied to a dereferenced pointer to a polymorphic type, the set consists ofstd::bad_typeid.
      6) Ife is anew-expression with a non-constant array size, and the selected allocation function has a non-empty set of potential exceptions, the set consists ofstd::bad_array_new_length.
      (since C++11)
      void f()throw(int);// f()'s set is "int"void g();// g()'s set is the set of all types struct A{ A();};// "new A"'s set is the set of all typesstruct B{ B()noexcept;};// "B()"'s set is emptystruct D(){ D()throw(double);};// new D's set is the set of all types

      All implicitly-declared member functionsand inheriting constructors(since C++11)have exception specifications, selected as follows:

      • If the set of potential exceptions is the set of all types, the implicit exception specificationallows all exceptions (the exception specification is considered present, even though it is inexpressible in code and behaves as if there is no exception specification)(until C++11)isnoexcept(false)(since C++11).
      • Otherwise, If the set of potential exceptions is not empty, the implicit exception specification lists every type from the set.
      • Otherwise, the implicit exception specification isthrow()(until C++11)noexcept(true)(since C++11).
      struct A{    A(int=(A(5),0))noexcept;    A(const A&)throw();    A(A&&)throw();    ~A()throw(X);}; struct B{    B()throw();    B(const B&)=default;// exception specification is "noexcept(true)"    B(B&&,int=(throw Y(),0))noexcept;    ~B()throw(Y);}; int n=7;struct D:public A,public B{// May throw an exception of a type that would match a handler of type// std​::​bad_array_new_length, but does not throw a bad allocation exception(void*) new(std::nothrow)int[n]; // D may have the following implicitly-declared members:// D::D() throw(X, std::bad_array_new_length);// D::D(const D&) noexcept(true);// D::D(D&&) throw(Y);// D::~D() throw(X, Y);};

      [edit]Notes

      Clang considers the rule of instantiation of dynamic exception specification is changed in C++11 byCWG1330, seeLLVM #56349.

      [edit]Keywords

      throw

      [edit]Example

      Note: best be compiled in C++98 mode to avoid warnings. Incompatible with C++17 and newer revisions.

      Run this code
      #include <cstdlib>#include <exception>#include <iostream> class X{};class Y{};class Z:public X{};class W{}; void f()throw(X, Y){bool n=false; if(n)throw X();// OK, would call std::terminate()if(n)throw Z();// also OK throw W();// will call std::unexpected()} void handler(){std::cerr<<"That was unexpected!\n";// flush neededstd::abort();} int main(){std::set_unexpected(handler);    f();}

      Output:

      That was unexpected!

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 25C++98the behavior of assignment and initialization
      between pointers to members with different
      exception specifications was unspecified
      apply the restriction
      for function pointers
      and references
      CWG 973C++98exception specification may contain functions types, but the
      corresponding function pointer conversion was not specified
      specified
      CWG 1330C++98an exception specification might be eagerly instantiatedit is only instantiated only if needed
      CWG 1267C++11rvalue reference types were allowed in exception specificationsnot allowed
      CWG 1351C++98
      C++11
      default argument (C++98) and default member initializer
      (C++11) were ignored in implicit exception specification
      made considered
      CWG 1777C++11throw(T...) was not a non-throwing
      specification even ifT is an empty pack
      it is non-throwing
      if the pack is empty
      CWG 2191C++98the set of potential exceptions of atypeid expression
      might containbad_typeid even if it cannot be thrown
      containsbad_typeid
      only if it can be thrown

      [edit]See also

      noexcept specifier(C++11) specifies whether a function could throw exceptions[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/except_spec&oldid=174586"

      [8]ページ先頭

      ©2009-2025 Movatter.jp