This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


1778. exception-specification in explicitly-defaulted functions

Section: 9.5.2  [dcl.fct.def.default]     Status: C++14     Submitter: USA     Date: 2013-09-25

N3690 comment US 23

[Moved to DR at the February, 2014 meeting.]

According to 9.5.2 [dcl.fct.def.default] paragraph 2,

An explicitly-defaulted function may be declared constexpr only if it would have been implicitly declared as constexpr, and may have an explicit exception-specification only if it is compatible (14.5 [except.spec]) with the exception-specification on the implicit declaration.

The requirement for exception-specifications has unfortunate consequences for the standard library component atomic, as described in LWG issue 2165: the component cannot be used with a T unless T is nothrow default constructible, even if the std::atomic<T> variable is never default initialized.

Proposed resolution (September, 2013):

Change 9.5.2 [dcl.fct.def.default] paragraphs 2 and 3 as follows:

An explicitly-defaulted function may be declared constexpr only if it would have been implicitly declared as constexpr, and may have an explicit exception-specification only if it is compatible (14.5 [except.spec]) with the exception-specification on the implicit declaration. If a function is explicitly defaulted on its first declaration,

If a function that is explicitly defaulted has an explicit exception-specification that is not compatible (14.5 [except.spec]) with the exception-specification on the implicit declaration, then

[Example:

  struct S {
    constexpr S() = default;            // ill-formed: implicit S() is not constexpr
    S(int a = 0) = default;             // ill-formed: default argument
    void operator=(const S&) = default; // ill-formed: non-matching return type
    ~S() throw(int) = default;          // ill-formed deleted: exception specification does not match
  private:
    int i;
    S(S&);                              // OK: private copy constructor
  };
  S::S(S&) = default;                   // OK: defines copy constructor

end example]

Additional note, January, 2014:

The proposed resolution appears to have the undesirable implication that a special member function could become deleted after the class is complete. For example, given

  struct S {
    S() noexcept(false) = default;
  };

we need to check that the explicit exception specification is compatible with the one on the implicit declaration. After the resolution of issue 1330, the class is regarded as complete within exception-specifications, per 11.4 [class.mem] paragraph 2. This implies that the explicit exception-specification can only be checked once the class is complete.

The issue has been returned to "review" status to allow discussion of this concern.