This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Moved to DR at the November, 2014 meeting.]
The determination of theexception-specification for animplicitly-declared special member function, as described in14.5 [except.spec] paragraph 14, does not take into account thefact that nonstatic data member initializers and default arguments indefault constructors can containthrow-expressions, which arenot part of theexception-specification of any function that is“directly invoked” by the implicit definition. Also, thereference to “directly invoked” functions is notrestricted to potentially-evaluated expressions, thus possiblyincluding irrelevantexception-specifications.
Additional note (August, 2012):
The direction established by CWG for resolving this issue was toconsider functions called from default arguments and non-static datamember initializers in determining theexception-specification.This leads to a problem with ordering: because non-static data memberinitializers can refer to members declared later, their effect cannotbe known until the end of the class. However, a non-static datamember initializer could possibly refer to an implicitly-declaredconstructor, either its own or that of an enclosing class.
Proposed resolution (October, 2012) [SUPERSEDED]:
Add the following two new paragraphs and make the indicatedchanges to 14.5 [except.spec] paragraph 14:
Aset of potential exceptions may contain types and thespecial value “any.” Theset of potential exceptions ofan expression is the union of all sets of potential exceptions ofeach potentially-evaluated subexpressione:
Ife is a call to a function, member function,function pointer, or member function pointer (including implicitcalls, such as a call to the allocation function in anew-expression):
if it has a non-throwingexception-specification or the call is a core constantexpression (7.7 [expr.const]), the set isempty;
otherwise, if it has adynamic-exception-specification, the set consists of every type inthatdynamic-exception-specification;
otherwise, the set consists of “any.”
Ife is athrow-expression (14.2 [except.throw]), the set consists of the type of the exception objectthat would be initialized by the operand if present, or“any” otherwise.
Ife is adynamic_cast expression thatcasts to a reference type and requires a run-time check (7.6.1.7 [expr.dynamic.cast]), the set consists of the typestd::bad_cast.
Ife is atypeid expression applied to aglvalue expression whose type is a polymorphic class type(7.6.1.8 [expr.typeid]), the set consists of the typestd::bad_typeid.
Ife is anew-expression with anon-constantexpression in thenoptr-new-declarator(7.6.2.8 [expr.new]), the set also includes the typestd::bad_array_new_length.
Otherwise, the set is the empty set.
Theset of potential exceptions of a functionf of some classX, wheref is an inheritingconstructor or an implicitly-declared special member function, isdefined as follows:
Iff is a constructor, the set is the union of thesets of potential exceptions of the constructor invocations forX's non-variant non-static data members, forX'sdirect base classes, and, ifX is non-abstract (11.7.4 [class.abstract]), forX's virtual base classes, as selected byoverload resolution for the implicit definition off(11.4.5 [class.ctor]), including default argument expressionsused in such invocations. [Note: Even though destructors for fullyconstructed subobjects are invoked when an exception is thrown duringthe execution of a constructor (14.3 [except.ctor]), theirexception-specifications do not contribute to theexception-specification of the constructor, because anexception thrown from such a destructor could never escape theconstructor (14.2 [except.throw], 14.6.2 [except.terminate]). —end note]
Iff is a default constructor or inheritingconstructor, the set also contains all members of the sets ofpotential exceptions of the initialization of non-static data membersfrombrace-or-equal-initializers.
Iff is an assignment operator, the set is theunion of the sets of potential exceptions of the assignment operatorinvocations forX's non-variant non-static data members andforX's virtual and direct base classes, as selected byoverload resolution for the implicit definition off(11.4.5.3 [class.copy.ctor]), including default argument expressionsused in such invocations.
Iff is a destructor, the set is the union of thesets of potential exceptions of the destructor invocations forX's non-variant non-static data members and forX'svirtual and direct base classes.
An inheriting constructor (_N4527_.12.9 [class.inhctor]) and an
implicitly declaredimplicitly-declared specialmember function (11.4.4 [special])have anare considered to have an implicitexception-specification.Iff is an inheritingconstructor or an implicitly declared default constructor, copyconstructor, move constructor, destructor, copy assignment operator,or move assignment operator, its implicitexception-specification specifies thetype-idTif and only ifT is allowed by theexception-specification of a function directly invoked byf's implicit definition;f allows all exceptions ifany function it directly invokes allows all exceptions, andfhas theexception-specificationnoexcept(true) ifevery function it directly invokes allows no exceptions.The implicitexception-specification isnoexcept(false) if the set of potential exceptions of thefunction contains “any;” otherwise, if that setcontains at least one type, the implicit exception-specificationspecifies each type T contained in the set; otherwise, the implicitexception-specification isnoexcept(true).[Note: An instantiation of an inheriting constructor templatehas an impliedexception-specification as if it were anon-template inheriting constructor. —end note][Example:struct A { A(); A(const A&) throw(); A(A&&) throw(); ~A() throw(X); }; struct B { B() throw(); B(const B&) throw(); B(B&&, int = (throw Y(), 0)) throw(Y)noexcept; ~B() throw(Y); }; struct D : public A, public B { // Implicit declaration of D::D(); // Implicit declaration of D::D(const D&) noexcept(true); // Implicit declaration of D::D(D&&) throw(Y); // Implicit declaration of D::~D() throw(X, Y); };Furthermore, if...
Change 7.6.2.7 [expr.unary.noexcept] paragraph 3 as follows:
The result of the noexcept operator isfalse if
in apotentially-evaluated contexttheset of potentialexceptions of the expression(14.5 [except.spec])would containcontains“any” or at least one type andtrueotherwise.
a potentially evaluated call80 to afunction, member function, function pointer, or member functionpointer that does not have a non-throwingexception-specification (14.5 [except.spec]), unless thecall is a constant expression (7.7 [expr.const]),
a potentially evaluatedthrow-expression (14.2 [except.throw]),
a potentially evaluateddynamic_cast expressiondynamic_cast<T>(v), whereT is a referencetype, that requires a run-time check (7.6.1.7 [expr.dynamic.cast]),or
a potentially evaluatedtypeid expression (7.6.1.8 [expr.typeid]) applied to a glvalue expression whose type is apolymorphic class type (11.7.3 [class.virtual]).
Otherwise, the result istrue.
(This resolution also resolves issues1356 and1465.)
Additional note (October, 2012):
The preceding wording has been modified from the version thatwas reviewed following the October, 2012 meeting and thus has beenreturned to "review" status.
Additional note (March, 2013):
It has been suggested that it might be more consistent withother parts of the language, and particularly in view of thedeprecation ofdynamic-exception-specifications, if apotentially-throwing non-static data member initializer simply madean implicit constructornoexcept(false) instead ofgiving it a set of potential exception types.
Additional note, April, 2013:
One problem with the approach suggested in the preceding notewould be something like the following example:
struct S { virtual ~S() throw(int); }; struct D: S { };This approach would make the example ill-formed, becausethe derived class destructor would be declared to throwtypes not permitted by the base classdestructor'sexception-specification. A furtherelaboration on the suggestion above that would not have thisobjection would be to define alldynamic-exception-specifications as simply equivalent tonoexcept(false).
(See alsoissue 1639.)
Additional note, April, 2013:
The version of this resolution approved in Bristolassumed the underlying text of the C++11 IS; however, thewording of 14.5 [except.spec] paragraph 14 has beenchanged by previous resolutions, so this and the relatedissues are being returned to "review" status.
Proposed resolution, February, 2014 [SUPERSEDED]:
Change 14.5 [except.spec] paragraph 5 as follows:
If a virtual function has anexception-specification,all declarations, including the definition, of any functionthat overrides that virtual function in any derived classshall only allow exceptions that are allowed bytheexception-specification of the base class virtualfunction, unless the overriding function is defined asdeleted. [Example:...
Add the following two new paragraphs and change14.5 [except.spec] paragraph 14 as indicated:
Aset of potential exceptions may containtypes and the special value “any”. Theset ofpotential exceptions of an expression is the union ofall sets of potential exceptions of eachpotentially-evaluated subexpressione:
Ife is a core constant expression(7.7 [expr.const]), the set isempty.
Otherwise, ife is a function call(7.6.1.3 [expr.call]) whosepostfix-expressionis not a (possibly parenthesized)id-expression(_N4567_.5.1.1 [expr.prim.general]) or class member access(7.6.1.5 [expr.ref]), the set consists of“any”.
Otherwise, ife invokes a function,member function, or function pointer (including implicitcalls, such as to an overloaded operator or to an allocationfunction in anew-expression):
if its declaration has anon-throwingexception-specification, the set isempty;
otherwise, if its declaration hasadynamic-exception-specification, the set consistsof every type inthatdynamic-exception-specification;
otherwise, the set consists of“any”.
Ife is athrow-expression(14.2 [except.throw]), the set consists of the type ofthe exception object that would be initialized by theoperand if present, or “any” otherwise.
Ife is adynamic_cast expressionthat casts to a reference type and requires a run-time check(7.6.1.7 [expr.dynamic.cast]), the set consists of thetypestd::bad_cast.
Ife is atypeid expression appliedto a glvalue expression whose type is a polymorphic classtype (7.6.1.8 [expr.typeid]), the set consists of thetypestd::bad_typeid.
Ife is anew-expression with anon-constant expression in thenoptr-new-declarator(7.6.2.8 [expr.new]), the set also includes thetypestd::bad_array_new_length.
If none of the previous items applies, the set is theempty set.
Theset of potential exceptions of animplicitly-declared special member functionfof some classX is defined as follows:
Iff is a constructor, the set is theunion of the sets of potential exceptions of the constructorinvocations forX's non-variant non-static datamembers, forX's direct base classes, and,ifX is non-abstract (11.7.4 [class.abstract]),forX's virtual base classes, as selected byoverload resolution for the implicit definitionoff (11.4.5 [class.ctor]), including defaultargument expressions used in such invocations. [Note:Even though destructors for fully constructed subobjects areinvoked when an exception is thrown during the execution ofa constructor (14.3 [except.ctor]),theirexception-specifications do not contribute totheexception-specification of the constructor,because an exception thrown from such a destructor couldnever escape the constructor (14.2 [except.throw],14.6.2 [except.terminate]). —endnote]
Iff is a default constructor, the set alsocontains all members of the sets of potential exceptions ofthe initialization of non-static data membersfrombrace-or-equal-initializers.
Iff is an assignment operator, the set isthe union of the sets of potential exceptions of theassignment operator invocations forX's non-variantnon-static data members and forX's virtual anddirect base classes, as selected by overload resolution forthe implicit definition off(11.4.5.3 [class.copy.ctor]), including default argumentexpressions used in such invocations.
Iff is a destructor, the set is the unionof the sets of potential exceptions of the destructorinvocations forX's non-variant non-static datamembers and forX's virtual and direct baseclasses.
An inheriting constructor (_N4527_.12.9 [class.inhctor]) andan implicitly-declared special member function(11.4.4 [special])
haveareconsidered to haveanimplicitexception-specification.Iffis an inheriting constructor or an implicitly declareddefault constructor, copy constructor, move constructor,destructor, copy assignment operator, or move assignmentoperator, its implicitexception-specificationspecifies thetype-idT if and onlyifT is allowed bytheexception-specification of a function directlyinvoked byf's implicit definition;fallows all exceptions if any function it directly invokesallows all exceptions, andf hastheexception-specificationnoexcept(true) if every function it directlyinvokes allows no exceptions. [Note: It followsthatf has theexception-specificationnoexcept(true) if it invokes no otherfunctions. —end note][Note: Aninstantiation of an inheriting constructor template has animpliedexception-specification as if it were anon-template inheriting constructor. —end note]The implicitexception-specification isnoexcept(false) if the set of potential exceptions of thespecial member function contains “any”; otherwise, if thatset contains at least one type, theimplicitexception-specification specifies each typeT contained in the set; otherwise, theimplicitexception-specificationisnoexcept(true). [Example:struct A { A(); A(const A&) throw(); A(A&&) throw(); ~A() throw(X); }; struct B { B() throw(); B(const B&)= default; // Declaration ofB::B(const B&) noexcept(true)throw(); B(B&&, int = (throw Y(), 0))throw(Y)noexcept; ~B() throw(Y); }; struct D : public A, public B { // Implicit declaration of D::D(); // Implicit declaration of D::D(const D&) noexcept(true); // Implicit declaration of D::D(D&&) throw(Y); // Implicit declaration of D::~D() throw(X, Y); };Furthermore...
Change 7.6.2.7 [expr.unary.noexcept]paragraph 3 as follows:
The result of thenoexcept operatoris
falsetrueifin a potentially-evaluated contexttheset of potential exceptions oftheexpression(14.5 [except.spec])wouldcontainis empty, andfalseotherwise.
a potentially-evaluated call [[Footnote: Thisincludes implicit calls such as the call to an allocationfunction in anew-expression. —endfootnote] to a function, member function, functionpointer, or member function pointer that does not have anon-throwingexception-specification(14.5 [except.spec]), unless the call is a constantexpression (7.7 [expr.const]),
a potentially-evaluatedthrow-expression(14.2 [except.throw]),
a potentially-evaluateddynamic_cast expressiondynamic_cast<T>(v), whereT is areference type, that requires a run-time check(7.6.1.7 [expr.dynamic.cast]), or
a potentially-evaluatedtypeid expression(7.6.1.8 [expr.typeid]) applied to a glvalue expressionwhose type is a polymorphic class type(11.7.3 [class.virtual]).
Otherwise, the result istrue.
Additional note, May, 2014:
The current version of the proposed resolution only defines the set ofpotential exceptions for special member functions; since an inheritingconstructor is not a special member function, theexception-specification for an inheriting constructor isno longer specified.
In addition, the structure of the specification of the set ofpotential exceptions of an expression is unclear. If the bulletedlist is intended to be the definition of general statement (“unionof all sets of potential exceptions...”), it's incomplete becauseit doesn't consider exceptions thrown by the evaluation of functionarguments in a call, just the exceptions thrown by the function itself;if it's intended to be a list of exceptions to the general rule, therule about core constant expressions doesn't exclude unselectedsubexpressions that might throw, so those exceptions are incorrectincluded in the union.
The issue has been returned to "review"status to allow discussion of these points.
See also the discussion in messages25290 through25293.
Proposed resolution (June, 2014):
If a virtual function has anexception-specification, alldeclarations, including the definition, of any function thatoverrides that virtual function in any derived class shall onlyallow exceptions that are allowed bytheexception-specification of the base class virtualfunction, unless the overriding function is defined asdeleted. [Example:...
Add the following new paragraphs following 14.5 [except.spec] paragraph 13:
Anexception-specification is not considered part of afunction's type.
Apotential exception of a given context is eithera type that might be thrown as an exception or a pseudo-type,denoted by “any”, that represents the situation wherean exception of an arbitrary type might be thrown. A subexpressione1 of an expressione is animmediatesubexpression if there is no subexpressione2 ofesuch thate1 is a subexpression ofe2.
Theset of potential exceptions of a function, functionpointer, or member function pointerf is defined asfollows:
If the declaration off has a non-throwingexception-specification, the set is empty.
Otherwise, if the declaration off has adynamic-exception-specification, the set consists of everytype in thatdynamic-exception-specification.
Otherwise, the set consists of the pseudo-type“any”.
Theset of potential exceptions of an expressioneis empty ife is a core constant expression(7.7 [expr.const]). Otherwise, it is the union of the setsof potential exceptions of the immediate subexpressions ofe,including default argument expressions used in a function call,combined with a setS defined by the form ofe, asfollows:
Ife is a function call(7.6.1.3 [expr.call]):
If itspostfix-expression is a (possiblyparenthesized)id-expression (_N4567_.5.1.1 [expr.prim.general]),class member access (7.6.1.5 [expr.ref]), orpointer-to-member operation (7.6.4 [expr.mptr.oper]) whosecast-expression is anid-expression,S is theset of potential exceptions of the entity selected by thecontainedid-expression (after overload resolution, ifapplicable).
Otherwise,S contains the pseudo-type“any”.
Ife implicitly invokes a function (such asan overloaded operator, an allocation function in anew-expression, or a destructor ife is afull-expression),S is the set of potential exceptions ofthe function.
ife is athrow-expression(14.2 [except.throw]),S consists of the type ofthe exception object that would be initialized by the operand,if present, or the pseudo-type “any”otherwise.
ife is adynamic_cast expressionthat casts to a reference type and requires a run-time check(7.6.1.7 [expr.dynamic.cast]),S consists of the typestd::bad_cast.
ife is atypeid expression appliedto a glvalue expression whose type is a polymorphic class type(7.6.1.8 [expr.typeid]),S consists of the typestd::bad_typeid.
ife is anew-expression with anon-constantexpression in thenoptr-new-declarator(7.6.2.8 [expr.new]),S consists of the typestd::bad_array_new_length.
[Example: Given the following declarations
void f() throw(int); void g(); struct A { A(); }; struct B { B() noexcept; }; struct D() { D() throw (double); };the set of potential exceptions for some sample expressionsis:
forf(), the set consists ofint;
forg(), the set consists of“any”;
fornew A, the set consists of“any”;
forB(), the set is empty;
fornew D, the set consists of“any” anddouble.
—end example]
Given a member functionf of some classX,wheref is an inheriting constructor(_N4527_.12.9 [class.inhctor]) or an implicitly-declared special memberfunction, theset of potential exceptions of the implicitly-declaredmember functionf consists of all the members from thefollowing sets:
iff is a constructor,
the sets of potential exceptions of the constructorinvocations
forX's non-variant non-static datamembers,
forX's direct base classes, and
ifX is non-abstract (11.7.4 [class.abstract]),forX's virtual base classes,
(including default argument expressions used in suchinvocations) as selected by overload resolution for the implicitdefinition off (11.4.5 [class.ctor]).[Note: Even though destructors for fully-constructedsubobjects are invoked when an exception is thrown during theexecution of a constructor (14.3 [except.ctor]), theirexception-specifications do not contribute to theexception-specification of the constructor, because anexception thrown from such a destructor could never escape theconstructor (14.2 [except.throw], 14.6.2 [except.terminate]).—end note]
the sets of potential exceptions of the initializationof non-static data members frombrace-or-equal-initializersthat are not ignored (11.9.3 [class.base.init]);
iff is an assignment operator, the sets ofpotential exceptions of the assignment operator invocations forX's non-variant non-static data members and forX's direct base classes (including default argumentexpressions used in such invocations), as selected by overloadresolution for the implicit definition off(11.4.5.3 [class.copy.ctor]);
iff is a destructor, the sets of potentialexceptions of the destructor invocations forX'snon-variant non-static data members and forX's virtualand direct base classes.
Change 14.5 [except.spec] paragraph 14 as follows:
An inheriting constructor (_N4527_.12.9 [class.inhctor]) and an
implicitly declaredimplicitly-declaredspecial member function (11.4.4 [special])areconsidered to have animplicitexception-specification, as follows, wheref isthe member function andS is the set of potential exceptionsof the implicitly-declared member functionf:.
ifS contains the pseudo-type “any”,the implicitexception-specification isnoexcept(false);
otherwise, ifS contains at least one type, theimplicitexception-specification specifies each typeTcontained inS;
otherwise, the implicitexception-specification isnoexcept(true).
Iff is an inheritingconstructor or an implicitly declared default constructor, copyconstructor, move constructor, destructor, copy assignmentoperator, or move assignment operator, itsimplicitexception-specification specifiesthetype-idT if and only ifT isallowed by theexception-specification of a functiondirectly invoked byf's implicit definition;fallows all exceptions if any function it directly invokes allowsall exceptions, andf hastheexception-specificationnoexcept(true) ifevery function it directly invokes allows noexceptions. [Note: It follows thatf hastheexception-specificationnoexcept(true) if it invokes no other functions. —endnote][Note: An instantiation of an inheritingconstructor template has animpliedexception-specification as if it were anon-template inheriting constructor. —end note][Example: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; // Declaration ofB::B(const B&) noexcept(true) B(B&&, int = (throw Y(), 0))throw(Y)noexcept; ~B() throw(Y); }; int n = 7; struct D : public A, public B { int * p = new (std::nothrow) int[n]; // Implicit declaration ofD::D() throw(X, std::bad_array_new_length);// Implicit declaration ofD::D();// Implicit declaration ofD::D(const D&) noexcept(true); // Implicit declaration ofD::D(D&&) throw(Y); // Implicit declaration ofD::~D() throw(X, Y); };
Change 7.6.2.7 [expr.unary.noexcept] paragraph 3 as follows:
The result of thenoexcept operatoris
falsetrue ifin apotentially-evaluated contexttheset of potentialexceptions of the expressionwould containis empty, andfalse otherwise.
a potentially-evaluated call83 to afunction, member function, function pointer, or member functionpointer that does not have anon-throwingexception-specification(14.5 [except.spec]), unless the call is a constantexpression (7.7 [expr.const]),
a potentially-evaluatedthrow-expression(14.2 [except.throw]),
a potentially-evaluateddynamic_cast expressiondynamic_cast<T>(v), whereT is a reference type, thatrequires a run-time check (7.6.1.7 [expr.dynamic.cast]), or
a potentially-evaluatedtypeid expression(7.6.1.8 [expr.typeid]) applied to a glvalue expressionwhose type is a polymorphic class type(11.7.3 [class.virtual]).
Otherwise, the result istrue.
This resolution also resolves issues1356,1465,and1639.