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 April, 2013 meeting.]
The use ofnoexcept specifiers can cause instantiation ofclasses and functions that are not actually needed in the program,just to be able to complete the declaration. The actual value of theexpression in thenoexcept-specification is only needed if thefunction is defined (i.e., instantiated) or called, so it wouldsignificantly reduce the number of instantiations (and avoid certainkinds of errors when the value is currently required before a class iscomplete) ifexception-specifications were treated like defaultarguments and only instantiated when they are actually needed.
Proposed resolution (February, 2012):
Change 13.7 [temp.decls] paragraph 2 as follows:
For purposes of name lookup and instantiation, default argumentsandexception-specifications of function templatesand default argumentsandexception-specificationsof member functions of class templates are considered definitions;each default argumentorexception-specification isa separate definition which is unrelated to the function templatedefinition or to any other default argumentsorexception-specifications.
Change 13.8 [temp.res] paragraph 11 as follows:
[Note: For purposes of name lookup, default argumentsandexception-specifications of function templates andfdefault argumentsandexception-specifications ofmember functions of class templates are considered definitions(14.5). —end note]
Add a new paragraph following 13.8.4.1 [temp.point] paragraph 2:
If a function template or member function of a class template iscalled in a way which uses the definition of a default argument ofthat function template or member function, the point of instantiationof the default argument is the point of instantiation of the functiontemplate or member function specialization.
For anexception-specification of a function templatespecialization or specialization of a member function of a classtemplate, if theexception-specification is implicitlyinstantiated because it is needed by another template specializationand the context that requires it depends on a template parameter, thepoint of instantiation of theexception-specification is thepoint of instantiation of the specialization that requiresit. Otherwise, the point of instantiation for such anexception-specification immediately follows the namespace scopedeclaration or definition that requires theexception-specification.
Change 13.9.2 [temp.inst] paragraph 1 as follows:
...The implicit instantiation of a class template specializationcauses the implicit instantiation of the declarations, but not of thedefinitions,ordefault arguments,orexception-specifications, of the class member functions,member classes...
Add a new paragraph following 13.9.2 [temp.inst] paragraph 13:
Each default argument is instantiated independently. [Example:... —end example]
If theexception-specification of a specialization of afunction template or member function of a class template has not yetbeen instantiated, but is needed (e.g., to instantiate the functiondefinition, to evaluate anoexcept-expression (7.6.2.7 [expr.unary.noexcept]), or to compare against theexception-specification of another declaration), the dependentnames are looked up, the semantic constraints are checked, and theinstantiation of any template used in theexception-specification is done as if it were being done aspart of instantiating the declaration of the specialization. Anexception-specification is not instantiated in order to calculate theexception-specification of a defaulted function in a derivedclass until theexception-specification of the derived memberfunction becomes necessary.
Change the note 13.10.3 [temp.deduct] paragraph 7 asfollows:
...[Note: The equivalent substitution in exceptionspecifications is done only when thefunctionexception-specification is instantiated, at whichpoint a program is ill-formed if the substitution results in aninvalid type or expression. —end note]
Add a new paragraph following 14.5 [except.spec] paragraph 15:
A deallocation function (6.8.6.5.3 [basic.stc.dynamic.deallocation]) with no explicitexception-specification is treated as if it were specified withnoexcept(true).
Theexception-specification of a function templatespecialization is not instantiated along with the functiondeclaration; it is instantiated when needed (13.9.2 [temp.inst]). Theexception-specification of animplicitly-declared special member function is also evaluated asneeded. [Note: Therefore, an implicit declaration of a memberfunction of a derived class does not require theexception-specification of a base member function to beinstantiated. —end note]
Notes from the February, 2012 meeting:
There should be a specific definition of when anexception-specification is needed and must thus be instantiated.
Additional discussion (September, 2012):
Daveed Vandevoorde brought up two additional points. First, therule should be crafted so that an example like the following isill-formed:
template<class T> T f() noexcept(sizeof(T) < 4); int main() { decltype(f<void>()) *p; }Even though theexception-specification is not needed here,it should be instantiated (because of the unevaluated reference tof) in order to catch the ill-formedsizeof(T).
In addition, the proposed change creates an asymmetry between classtemplates and ordinary classes:
struct S { void f() noexcept(sizeof(g()) < 8); // Invalid forward reference. static int g(); };but
template<typename> struct X { void f() noexcept(sizeof(g()) < 8); // Okay. static int g(); };If the proposed change is adopted, the rules forexception-specifications in ordinary classes should be revisedto make the parallel usage well-formed.
Proposed resolution (October, 2012):
Change 6.4.7 [basic.scope.class] paragraph 1 #1 asfollows:
The potential scope of a name declared in a class consists not only ofthe declarative region following the name's point of declaration, butalso of all function bodies, default arguments,exception-specifications, andbrace-or-equal-initializers of non-static data members in thatclass (including such things in nested classes).
Change 6.5.3 [basic.lookup.unqual] paragraph 7 as follows:
A name used in the definition of a classX outside of amember function body, default argument,exception-specification,brace-or-equal-initializer of a non-static data member, ornested class definition29 shall be declared in one of thefollowing ways:...
Change 6.5.3 [basic.lookup.unqual] paragraph 8 as follows:
For the members of a classX, a name used in a memberfunction body, in a default argument,in anexception-specification, in thebrace-or-equal-initializer of a non-static data member(11.4 [class.mem]), or in the definition of a class memberoutside of the definition ofX, following the member'sdeclarator-id31 , shall be declared in one of thefollowing ways:...
Change 11.4 [class.mem] paragraph 2 as follows:
A class is considered a completely-defined object type (6.9 [basic.types]) (or complete type) at the closing } of theclass-specifier. Within the classmember-specification,the class is regarded as complete within function bodies, defaultarguments,exception-specifications, andbrace-or-equal-initializers for non-static data members(including such things in nested classes). Otherwise it is regarded asincomplete within its own classmember-specification.
Change 13.7 [temp.decls] paragraph 2 as follows:
For purposes of name lookup and instantiation, default argumentsandexception-specifications of function templatesand default argumentsandexception-specificationsof member functions of class templates are considered definitions;each default argumentorexception-specification isa separate definition which is unrelated to the function templatedefinition or to any other default argumentsorexception-specifications.
Change 13.8 [temp.res] paragraph 11 as follows:
[Note: For purposes of name lookup, default argumentsandexception-specifications of function templates anddefault argumentsandexception-specifications ofmember functions of class templates are considered definitions(13.7 [temp.decls]). —end note]
Add the following as a new paragraph after 13.8.4.1 [temp.point] paragraph 2:
If a function template or member function of a class template iscalled in a way which uses the definition of a default argument ofthat function template or member function, the point of instantiationof the default argument is the point of instantiation of the functiontemplate or member function specialization.
For anexception-specification of a function templatespecialization or specialization of a member function of a classtemplate, if theexception-specification is implicitlyinstantiated because it is needed by another template specializationand the context that requires it depends on a template parameter, thepoint of instantiation of theexception-specification is thepoint of instantiation of the specialization that requiresit. Otherwise, the point of instantiation for such anexception-specification immediately follows the namespace scopedeclaration or definition that requires theexception-specification.
Change 13.9.2 [temp.inst] paragraph 1 as follows:
Unless a class template specialization has been explicitlyinstantiated (13.9.3 [temp.explicit]) or explicitly specialized(13.9.4 [temp.expl.spec]), the class template specialization isimplicitly instantiated when the specialization is referenced in acontext that requires a completely-defined object type or when thecompleteness of the class type affects the semantics of the program.The implicit instantiation of a class template specialization causesthe implicit instantiation of the declarations, but not of thedefinitions,ordefault arguments,orexception-specifications of the class member functions,member classes, scoped member enumerations, static data members andmember templates; and it causes the implicit instantiation of thedefinitions of unscoped member enumerations and member anonymousunions. However, for the purpose...
Insert the following as a new paragraph immediately preceding13.9.2 [temp.inst] paragraph 14:
Theexception-specification of a function templatespecialization is not instantiated along with the functiondeclaration; it is instantiated when needed (14.5 [except.spec]). If such anexception-specification is needed buthas not yet been instantiated, the dependent names are looked up, thesemantics constraints are checked, and the instantiation of anytemplate used in theexception-specification is done as if itwere being done as part of instantiating the declaration of thespecialization at that point.
[Note: 13.8.4.1 [temp.point] defines the point ofinstantiation of a template specialization. —end note]
Change 13.10.3 [temp.deduct] paragraph 7 as follows:
The substitution occurs in all types and expressions that are used inthe function type and in template parameter declarations. Theexpressions include not only constant expressions such as those thatappear in array bounds or as nontype template arguments but alsogeneral expressions (i.e., non-constant expressions) inside sizeof,decltype, and other contexts that allow non-constant expressions.[Note: The equivalent substitution in exception specificationsis done only when thefunctionexception-specification is instantiated, at whichpoint a program is ill-formed if the substitution results in aninvalid type or expression. —end note]
Change 14.5 [except.spec] paragraph 2 as follows:
...A type denoted in anexception-specification shall notdenote an incomplete typeother than a class currently beingdefined. A type denoted in anexception-specificationshall not denote a pointer or reference to an incomplete type, otherthancvvoid*or a pointer or reference to aclass currently being defined. A typecvT,“array ofT”, or “function returningT” denoted in anexception-specification isadjusted to typeT, “pointer toT”, or“pointer to function returningT” respectively.
Add the following as a new paragraph following14.5 [except.spec] paragraph 15:
A deallocation function (6.8.6.5.3 [basic.stc.dynamic.deallocation]) with noexplicitexception-specification is treated as if it werespecified withnoexcept(true).
Anexception-specification is considered to beneeded when:
in an expression, the function is the unique lookupresult or the selected member of a set of overloaded functions(6.5 [basic.lookup], 12.2 [over.match], 12.3 [over.over]);
the function is odr-used (6.3 [basic.def.odr]) or, ifit appears in an unevaluated operand, would be odr-used if theexpression were potentially-evaluated;
theexception-specification is compared to that of anotherdeclaration (e.g. an explicit specialization or an overriding virtualfunction);
the function is defined; or
theexception-specification is needed for a defaulted specialmember function that calls the function. [Note: A defaulteddeclaration does not require theexception-specification of abase member function to be evaluated until the implicitexception-specification of the derived function is needed, butan explicitexception-specification needs the implicitexception-specification to compareagainst. —end note]
Theexception-specification of a defaulted special memberfunction is evaluated as described above only when needed; similarly,theexception-specification of a specialization of a functiontemplate or member function of a class template is instantiated onlywhen needed.
[Note: this resolution reverses the decision inissue 1308.]