This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[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,
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-formeddeleted: 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.