Title
exception-specification in explicitly-defaulted functions
Status
c++14
Section
9.5.2 [dcl.fct.def.default]
Submitter
USA

Created on 2013-09-25.00:00:00 last changed 113 months ago

Messages

Date: 2014-02-15.00:00:00

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

Date: 2014-01-20.00:00:00

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.

Date: 2013-09-15.00:00:00

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,

  • it is implicitly considered to be constexpr if the implicit declaration would be, and,

  • it is implicitly considered to have the same exception-specification as if it had been implicitly declared (14.5 [except.spec]).

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

  • if the function is explicitly defaulted on its first declaration, it is defined as deleted;

  • otherwise, the program is ill-formed.

[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]

Date: 2013-09-25.00:00:00
N3690 comment US 23

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.

History
Date User Action Args
2014-11-24 00:00:00adminsetstatus: dr -> c++14
2014-03-03 00:00:00adminsetmessages: + msg4951
2014-03-03 00:00:00adminsetstatus: review -> dr
2014-01-20 00:00:00adminsetmessages: + msg4743
2014-01-20 00:00:00adminsetstatus: ready -> review
2013-10-14 00:00:00adminsetmessages: + msg4592
2013-09-25 00:00:00admincreate