|
|
|
15
[ Note: Except for reference and pointer types, a major array bound is not part of a function parameter type
and cannot be deduced from an argument:
template<int i> void f1(int a[10][i]);
template<int i> void f2(int a[i][20]);
template<int i> void f3(int (&a)[i][20]);
void g() {
int v[10][20];
f1(v);
// OK: i deduced to be 20
f1<20>(v);
// OK
f2(v);
// error: cannot deduce template-argument i
f2<10>(v);
// OK
f3(v);
// OK: i deduced to be 10
}
— end note ]
16
[Note: If, in the declaration of a function template with a non-type template parameter, the non-type
template parameter is used in a subexpression in the function parameter list, the expression is a non-deduced
context as specified above. [ Example:
template <int i> class A { /* ... */ };
template <int i> void g(A<i+1>);
template <int i> void f(A<i>, A<i+1>);
void k() {
A<1> a1;
A<2> a2;
g(a1);
// error: deduction fails for expression i+1
g<0>(a1);
// OK
f(a1, a2);
// OK
}
— end example ]
— end note ]
17
[Note: Template parameters do not participate in template argument deduction if they are used only in
non-deduced contexts. For example,
template<int i, typename T>
T deduce(typename A<T>::X x,
// T is not deduced here
T t,
// but T is deduced here
typename B<i>::Y y);
// i is not deduced here
A<int> a;
B<77> b;
int
x = deduce<77>(a.xm, 62, b.ym);
// T is deduced to be int, a.xm must be convertible to A<int>::X
// i is explicitly specified to be 77, b.ym must be convertible to B<77>::Y
— end note ]
18
If P has a form that contains <i>, and if the type of i differs from the type of the corresponding template
parameter of the template named by the enclosing simple-template-id, deduction fails. If P has a form that
contains [i], and if the type of i is not an integral type, deduction fails.145 [ Example:
template<int i> class A { /* ... */ };
template<short s> void f(A<s>);
void k1() {
A<1> a;
f(a);
// error: deduction fails for conversion from int to short
f<1>(a);
// OK
}
template<const short cs> class B { };
template<short s> void g(B<s>);
145) Although the template-argument corresponding to a template-parameter of type bool may be deduced from an array bound,
the resulting value will always be true because the array bound will be nonzero.
§ 17.9.2.5
382
void k2() {
B<1> b;
g(b);
// OK: cv-qualifiers are ignored on template parameter types
}
— end example ]
19
A template-argument can be deduced from a function, pointer to function, or pointer-to-member-function
type.
[ Example:
template<class T> void f(void(*)(T,int));
template<class T> void foo(T,int);
void g(int,int);
void g(char,int);
void h(int,int,int);
void h(char,int);
int m() {
f(&g);
// error: ambiguous
f(&h);
// OK: void h(char,int) is a unique match
f(&foo);
// error: type deduction fails because foo is a template
}
— end example ]
20
A template type-parameter cannot be deduced from the type of a function default argument. [ Example:
template <class T> void f(T = 5, T = 7);
void g() {
f(1);
// OK: call f<int>(1,7)
f();
// error: cannot deduce T
f<int>();
// OK: call f<int>(5,7)
}
— end example ]
21
The template-argument corresponding to a template template-parameter is deduced from the type of the
template-argument of a class template specialization used in the argument list of a function call. [ Example:
template <template <class T> class X> struct A { };
template <template <class T> class X> void f(A<X>) { }
template<class T> struct B { };
A<B> ab;
f(ab);
// calls f(A<B>)
— end example ]
22
[ Note: Template argument deduction involving parameter packs (17.6.3) can deduce zero or more arguments
for each parameter pack.
— end note ] [ Example:
template<class> struct X { };
template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { };
template<class ... Types> struct Y { };
template<class T, class ... Types> struct Y<T, Types& ...> { };
template<class ... Types> int f(void (*)(Types ...));
void g(int, float);
X<int> x1;
// uses primary template
X<int(int, float, double)> x2;
// uses partial specialization; ArgTypes contains float, double
X<int(float, int)> x3;
// uses primary template
Y<> y1;
// use primary template; Types is empty
Y<int&, float&, double&> y2;
// uses partial specialization; T is int&, Types contains float, double
Y<int, float, double> y3;
// uses primary template; Types contains int, float, double
int fv = f(g);
// OK; Types contains int, float
— end example ]
§ 17.9.2.5
383
17.9.2.6
Deducing template arguments from a function declaration
[temp.deduct.decl]
1
In a declaration whose declarator-id refers to a specialization of a function template, template argument
deduction is performed to identify the specialization to which the declaration refers. Specifically, this is done
for explicit instantiations (17.8.2), explicit specializations (17.8.3), and certain friend declarations (17.6.4).
This is also done to determine whether a deallocation function template specialization matches a placement
operator new (6.6.4.4.2, 8.5.2.4). In all these cases, P is the type of the function template being considered
as a potential match and A is either the function type from the declaration or the type of the deallocation
function that would match the placement operator new as described in 8.5.2.4. The deduction is done as
described in 17.9.2.5.
2
If, for the set of function templates so considered, there is either no match or more than one match after
partial ordering has been considered (17.6.6.2), deduction fails and, in the declaration cases, the program is
ill-formed.
17.9.3
Overload resolution
[temp.over]
1
A function template can be overloaded either by (non-template) functions of its name or by (other) function
templates of the same name. When a call to that name is written (explicitly, or implicitly using the operator
notation), template argument deduction (17.9.2) and checking of any explicit template arguments (17.3)
are performed for each function template to find the template argument values (if any) that can be used
with that function template to instantiate a function template specialization that can be invoked with
the call arguments. For each function template, if the argument deduction and checking succeeds, the
template-arguments (deduced and/or explicit) are used to synthesize the declaration of a single function
template specialization which is added to the candidate functions set to be used in overload resolution. If,
for a given function template, argument deduction fails or the synthesized function template specialization
would be ill-formed, no such function is added to the set of candidate functions for that template. The
complete set of candidate functions includes all the synthesized declarations and all of the non-template
overloaded functions of the same name. The synthesized declarations are treated like any other functions in
the remainder of overload resolution, except as explicitly noted in 16.3.3.146
2
[ Example:
template<class T> T max(T a, T b) { return a>b?a:b; }
void f(int a, int b, char c, char d) {
int m1 = max(a,b);
// max(int a, int b)
char m2 = max(c,d);
// max(char a, char b)
int m3 = max(a,c);
// error: cannot generate max(int,char)
}
Adding the non-template function
int max(int,int);
to the example above would resolve the third call, by providing a function that could be called for max(a,c)
after using the standard conversion of char to int for c.
— end example ]
3
[ Example: Here is an example involving conversions on a function argument involved in template-argument
deduction:
template<class T> struct B { /* ... */ };
template<class T> struct D : public B<T> { /* ... */ };
template<class T> void f(B<T>&);
void g(B<int>& bi, D<int>& di) {
f(bi);
// f(bi)
f(di);
// f((B<int>&)di)
}
— end example ]
146) The parameters of function template specializations contain no template parameter types. The set of conversions allowed on
deduced arguments is limited, because the argument deduction process produces function templates with parameters that either
match the call arguments exactly or differ only in ways that can be bridged by the allowed limited conversions. Non-deduced
arguments allow the full range of conversions. Note also that 16.3.3 specifies that a non-template function will be given preference
over a template specialization if the two functions are otherwise equally good candidates for an overload match.
§ 17.9.3
384
4
[ Example: Here is an example involving conversions on a function argument not involved in template-parameter
deduction:
template<class T> void f(T*,int);
// #1
template<class T> void f(T,char);
// #2
void h(int* pi, int i, char c) {
f(pi,i);
// #1: f<int>(pi,i)
f(pi,c);
// #2: f<int*>(pi,c)
f(i,c);
// #2: f<int>(i,c);
f(i,i);
// #2: f<int>(i,char(i))
}
— end example ]
5
Only the signature of a function template specialization is needed to enter the specialization in a set of
candidate functions. Therefore only the function template declaration is needed to resolve a call for which a
template specialization is a candidate. [ Example:
template<class T> void f(T);
// declaration
void g() {
f("Annemarie");
// call of f<const char*>
}
The call of f is well-formed even if the template f is only declared and not defined at the point of the call.
The program will be ill-formed unless a specialization for f<const char*>, either implicitly or explicitly
generated, is present in some translation unit.
— end example ]
17.10
Deduction guides
[temp.deduct.guide]
1
Deduction guides are used when a template-name appears as a type specifier for a deduced class type (10.1.7.5).
Deduction guides are not found by name lookup. Instead, when performing class template argument
deduction (16.3.1.8), any deduction guides declared for the class template are considered.
deduction-guide:
explicitopt template-name ( parameter-declaration-clause ) -> simple-template-id ;
2
[ Example:
template<class T, class D = int>
struct S {
T data;
};
template<class U>
S(U) -> S<typename U::type>;
struct A {
using type = short;
operator type();
};
S x{A()};
// x is of type S<short, int>
— end example ]
3
The same restrictions apply to the parameter-declaration-clause of a deduction guide as in a function
declaration (11.3.5). The simple-template-id shall name a class template specialization. The template-name
shall be the same identifier as the template-name of the simple-template-id. A deduction-guide shall be
declared in the same scope as the corresponding class template and, for a member class template, with the
same access. Two deduction guide declarations in the same translation unit for the same class template shall
not have equivalent parameter-declaration-clauses.
§ 17.10
385
18
Exception handling
[except]
1
Exception handling provides a way of transferring control and information from a point in the execution of a
thread to an exception handler associated with a point previously passed by the execution. A handler will be
invoked only by throwing an exception in code executed in the handler’s try block or in functions called from
the handler’s try block.
try-block:
try compound-statement handler-seq
function-try-block:
try ctor-initializeropt compound-statement handler-seq
handler-seq:
handler handler-seqopt
handler:
catch ( exception-declaration ) compound-statement
exception-declaration:
attribute-specifier-seqopt type-specifier-seq declarator
attribute-specifier-seqopt type-specifier-seq abstract-declaratoropt
The optional attribute-specifier-seq in an exception-declaration appertains to the parameter of the catch
clause (18.3).
2
A try-block is a statement (Clause 9). [ Note: Within this Clause “try block” is taken to mean both try-block
and function-try-block.
— end note ]
3
A goto or switch statement shall not be used to transfer control into a try block or into a handler.
[ Example:
void f() {
goto l1;
// ill-formed
goto l2;
// ill-formed
try {
goto l1;
// OK
goto l2;
// ill-formed
l1: ;
} catch (...) {
l2: ;
goto l1;
// ill-formed
goto l2;
// OK
}
}
— end example ] A goto, break, return, or continue statement can be used to transfer control out of a try
block or handler. When this happens, each variable declared in the try block will be destroyed in the context
that directly contains its declaration. [ Example:
lab: try {
T1 t1;
try {
T2 t2;
if (condition )
goto lab;
} catch(...) { /* handler 2 */ }
} catch(...) { /* handler 1 */ }
Here, executing goto lab; will destroy first t2, then t1, assuming the condition does not declare a variable.
Any exception thrown while destroying t2 will result in executing handler 2; any exception thrown while
destroying t1 will result in executing handler 1.
— end example ]
4
A function-try-block associates a handler-seq with the ctor-initializer, if present, and the compound-statement.
An exception thrown during the execution of the compound-statement or, for constructors and destructors,
Exception handling
386
during the initialization or destruction, respectively, of the class’s subobjects, transfers control to a handler
in a function-try-block in the same way as an exception thrown during the execution of a try-block transfers
control to other handlers. [ Example:
int f(int);
class C {
int i;
double d;
public:
C(int, double);
};
C::C(int ii, double id)
try : i(f(ii)), d(id) {
// constructor statements
} catch (...) {
// handles exceptions thrown from the ctor-initializer and from the constructor statements
}
— end example ]
5
In this Clause, “before” and “after” refer to the “sequenced before” relation (6.8.1).
18.1
Throwing an exception
[except.throw]
1
Throwing an exception transfers control to a handler.
[Note: An exception can be thrown from one of
the following contexts: throw-expressions (8.5.17), allocation functions (6.6.4.4.1), dynamic_cast (8.5.1.7),
typeid (8.5.1.8), new-expressions (8.5.2.4), and standard library functions (20.4.1.4).
— end note ] An
object is passed and the type of that object determines which handlers can catch it. [ Example:
throw "Help!";
can be caught by a handler of const char* type:
try {
// ...
} catch(const char* p) {
// handle character string exceptions here
}
and
class Overflow {
public:
Overflow(char,double,double);
};
void f(double x) {
throw Overflow(’+’,x,3.45e107);
}
can be caught by a handler for exceptions of type Overflow:
try {
f(1.2);
} catch(Overflow& oo) {
// handle exceptions of type Overflow here
}
— end example ]
2
When an exception is thrown, control is transferred to the nearest handler with a matching type (18.3);
“nearest” means the handler for which the compound-statement or ctor-initializer following the try keyword
was most recently entered by the thread of control and not yet exited.
3
Throwing an exception copy-initializes (11.6, 15.8) a temporary object, called the exception object. An lvalue
denoting the temporary is used to initialize the variable declared in the matching handler (18.3). If the type
of the exception object would be an incomplete type or a pointer to an incomplete type other than cv void
the program is ill-formed.
§ 18.1
387
4
The memory for the exception object is allocated in an unspecified way, except as noted in 6.6.4.4.1. If a
handler exits by rethrowing, control is passed to another handler for the same exception object. The points
of potential destruction for the exception object are:
(4.1)
—
when an active handler for the exception exits by any means other than rethrowing, immediately after
the destruction of the object (if any) declared in the exception-declaration in the handler;
(4.2)
—
when an object of type std::exception_ptr (21.8.6) that refers to the exception object is destroyed,
before the destructor of std::exception_ptr returns.
Among all points of potential destruction for the exception object, there is an unspecified last one where the
exception object is destroyed. All other points happen before that last one (6.8.2.1). [ Note: No other thread
synchronization is implied in exception handling.
— end note ] The implementation may then deallocate
the memory for the exception object; any such deallocation is done in an unspecified way. [ Note: A thrown
exception does not propagate to other threads unless caught, stored, and rethrown using appropriate library
functions; see 21.8.6 and 33.6.
— end note ]
5
When the thrown object is a class object, the constructor selected for the copy-initialization as well as the
constructor selected for a copy-initialization considering the thrown object as an lvalue shall be non-deleted
and accessible, even if the copy/move operation is elided (15.8). The destructor is potentially invoked (15.4).
6
An exception is considered caught when a handler for that exception becomes active (18.3).
[Note: An
exception can have active handlers and still be considered uncaught if it is rethrown.
— end note ]
7
If the exception handling mechanism handling an uncaught exception (18.5.2) directly invokes a function
that exits via an exception, std::terminate is called (18.5.1). [ Example:
struct C {
C() { }
C(const C&) {
if (std::uncaught_exceptions()) {
throw 0;
// throw during copy to handler’s exception-declaration object (18.3)
}
}
};
int main() {
try {
throw C();
// calls std::terminate() if construction of the handler’s
// exception-declaration object is not elided (15.8)
} catch(C) { }
}
— end example ]
[Note: Consequently, destructors should generally catch exceptions and not let them
propagate.
— end note ]
18.2
Constructors and destructors
[except.ctor]
1
As control passes from the point where an exception is thrown to a handler, destructors are invoked by a
process, specified in this subclause, called stack unwinding.
2
The destructor is invoked for each automatic object of class type constructed, but not yet destroyed, since
the try block was entered. If an exception is thrown during the destruction of temporaries or local variables
for a return statement (9.6.3), the destructor for the returned object (if any) is also invoked. The objects
are destroyed in the reverse order of the completion of their construction. [ Example:
struct A { };
struct Y { ~Y() noexcept(false) { throw 0; } };
A f() {
try {
A a;
Y y;
A b;
return {};
// #1
} catch (...) {
}
§ 18.2
388
return {};
// #2
}
At #1, the returned object of type A is constructed. Then, the local variable b is destroyed (9.6). Next, the
local variable y is destroyed, causing stack unwinding, resulting in the destruction of the returned object,
followed by the destruction of the local variable a. Finally, the returned object is constructed again at #2.
— end example ]
3
If the initialization or destruction of an object other than by delegating constructor is terminated by an
exception, the destructor is invoked for each of the object’s direct subobjects and, for a complete object,
virtual base class subobjects, whose initialization has completed (11.6) and whose destructor has not yet
begun execution, except that in the case of destruction, the variant members of a union-like class are not
destroyed. The subobjects are destroyed in the reverse order of the completion of their construction. Such
destruction is sequenced before entering a handler of the function-try-block of the constructor or destructor,
if any.
4
If the compound-statement of the function-body of a delegating constructor for an object exits via an
exception, the object’s destructor is invoked. Such destruction is sequenced before entering a handler of the
function-try-block of a delegating constructor for that object, if any.
5
[ Note: If the object was allocated by a new-expression (8.5.2.4), the matching deallocation function (6.6.4.4.2),
if any, is called to free the storage occupied by the object.
— end note ]
18.3
Handling an exception
[except.handle]
1
The exception-declaration in a handler describes the type(s) of exceptions that can cause that handler to be
entered. The exception-declaration shall not denote an incomplete type, an abstract class type, or an rvalue
reference type. The exception-declaration shall not denote a pointer or reference to an incomplete type, other
than void*, const void*, volatile void*, or const volatile void*.
2
A handler of type “array of T” or function type T is adjusted to be of type “pointer to T”.
3
A handler is a match for an exception object of type E if
(3.1)
—
The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifier s),
or
(3.2)
—
the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
(3.3)
—
the handler is of type cv T or const T& where T is a pointer or pointer-to-member type and E is a
pointer or pointer-to-member type that can be converted to T by one or more of
(3.3.1)
—
a standard pointer conversion (7.11) not involving conversions to pointers to private or protected
or ambiguous classes
(3.3.2)
—
a function pointer conversion (7.13)
(3.3.3)
—
a qualification conversion (7.5), or
(3.4)
—
the handler is of type cv T or const T& where T is a pointer or pointer-to-member type and E is
std::nullptr_t.
[Note: A throw-expression whose operand is an integer literal with value zero does not match a handler of
pointer or pointer-to-member type. A handler of reference to array or function type is never a match for any
exception object (8.5.17).
— end note ]
[ Example:
class Matherr { /* ... */ virtual void vf(); };
class Overflow: public Matherr { /* ... */ };
class Underflow: public Matherr { /* ... */ };
class Zerodivide: public Matherr { /* ... */ };
void f() {
try {
g();
} catch (Overflow oo) {
// ...
} catch (Matherr mm) {
// ...
}
§ 18.3
389
}
Here, the Overflow handler will catch exceptions of type Overflow and the Matherr handler will catch
exceptions of type Matherr and of all types publicly derived from Matherr including exceptions of type
Underflow and Zerodivide. — end example ]
4
The handlers for a try block are tried in order of appearance. [ Note: This makes it possible to write handlers
that can never be executed, for example by placing a handler for a final derived class after a handler for a
corresponding unambiguous public base class.
— end note ]
5
A ... in a handler’s exception-declaration functions similarly to ... in a function parameter declaration; it
specifies a match for any exception. If present, a ... handler shall be the last handler for its try block.
6
If no match is found among the handlers for a try block, the search for a matching handler continues in a
dynamically surrounding try block of the same thread.
7
A handler is considered active when initialization is complete for the parameter (if any) of the catch clause.
[ Note: The stack will have been unwound at that point.
— end note ] Also, an implicit handler is considered
active when std::terminate() is entered due to a throw. A handler is no longer considered active when the
catch clause exits.
8
The exception with the most recently activated handler that is still active is called the currently handled
exception.
9
If no matching handler is found, the function std::terminate() is called; whether or not the stack is
unwound before this call to std::terminate() is implementation-defined (18.5.1).
10
Referring to any non-static member or base class of an object in the handler for a function-try-block of a
constructor or destructor for that object results in undefined behavior.
11
The scope and lifetime of the parameters of a function or constructor extend into the handlers of a function-
try-block.
12
Exceptions thrown in destructors of objects with static storage duration or in constructors of namespace-scope
objects with static storage duration are not caught by a function-try-block on the main function (6.8.3.1).
Exceptions thrown in destructors of objects with thread storage duration or in constructors of namespace-
scope objects with thread storage duration are not caught by a function-try-block on the initial function of
the thread.
13
If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.
14
The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block
of a constructor or destructor. Otherwise, flowing off the end of the compound-statement of a handler of a
function-try-block is equivalent to flowing off the end of the compound-statement of that function (see 9.6.3).
15
The variable declared by the exception-declaration, of type cv T or cv T&, is initialized from the exception
object, of type E, as follows:
(15.1)
—
if T is a base class of E, the variable is copy-initialized (11.6) from the corresponding base class subobject
of the exception object;
(15.2)
—
otherwise, the variable is copy-initialized (11.6) from the exception object.
The lifetime of the variable ends when the handler exits, after the destruction of any automatic objects
initialized within the handler.
16
When the handler declares an object, any changes to that object will not affect the exception object. When
the handler declares a reference to an object, any changes to the referenced object are changes to the exception
object and will have effect should that object be rethrown.
18.4
Exception specifications
[except.spec]
1
The predicate indicating whether a function cannot exit via an exception is called the exception specification
of the function. If the predicate is false, the function has a potentially-throwing exception specification,
otherwise it has a non-throwing exception specification. The exception specification is either defined implicitly,
or defined explicitly by using a noexcept-specifier as a suffix of a function declarator (11.3.5).
noexcept-specifier:
noexcept ( constant-expression )
noexcept
throw ( )
§ 18.4
390
2
In a noexcept-specifier, the constant-expression, if supplied, shall be a contextually converted constant
expression of type bool (8.6); that constant expression is the exception specification of the function type in
which the noexcept-specifier appears. A ( token that follows noexcept is part of the noexcept-specifier and
does not commence an initializer (11.6). The noexcept-specifier noexcept without a constant-expression is
equivalent to the noexcept-specifier noexcept(true). The noexcept-specifier throw() is deprecated (D.3),
and equivalent to the noexcept-specifier noexcept(true).
3
If a declaration of a function does not have a noexcept-specifier, the declaration has a potentially throwing
exception specification unless it is a destructor or a deallocation function or is defaulted on its first declaration,
in which cases the exception specification is as specified below and no other declaration for that function
shall have a noexcept-specifier. In an explicit instantiation (17.8.2) a noexcept-specifier may be specified,
but is not required. If a noexcept-specifier is specified in an explicit instantiation directive, the exception
specification shall be the same as the exception specification of all other declarations of that function. A
diagnostic is required only if the exception specifications are not the same within a single translation unit.
4
If a virtual function has a non-throwing exception specification, all declarations, including the definition, of
any function that overrides that virtual function in any derived class shall have a non-throwing exception
specification, unless the overriding function is defined as deleted. [ Example:
struct B {
virtual void f() noexcept;
virtual void g();
virtual void h() noexcept = delete;
};
struct D: B {
void f();
// ill-formed
void g() noexcept;
// OK
void h() = delete;
// OK
};
The declaration of D::f is ill-formed because it has a potentially-throwing exception specification, whereas
B::f has a non-throwing exception specification.
— end example ]
5
Whenever an exception is thrown and the search for a handler (18.3) encounters the outermost block of
a function with a non-throwing exception specification, the function std::terminate() is called (18.5.1).
[ Note: An implementation shall not reject an expression merely because, when executed, it throws or might
throw an exception from a function with a non-throwing exception specification.
— end note ] [ Example:
extern void f();
// potentially-throwing
void g() noexcept {
f();
// valid, even if f throws
throw 42;
// valid, effectively a call to std::terminate
}
The call to f is well-formed even though, when called, f might throw an exception.
— end example ]
6
An expression e is potentially-throwing if
(6.1)
—
e is a function call (8.5.1.2) whose postfix-expression has a function type, or a pointer-to-function type,
with a potentially-throwing exception specification, or
(6.2)
—
e implicitly invokes a function (such as an overloaded operator, an allocation function in a new-
expression, a constructor for a function argument, or a destructor if e is a full-expression (6.8.1)) that
is potentially-throwing, or
(6.3)
—
e is a throw-expression (8.5.17), or
(6.4)
—
e is a dynamic_cast expression that casts to a reference type and requires a runtime check (8.5.1.7), or
(6.5)
—
e is a typeid expression applied to a (possibly parenthesized) built-in unary * operator applied to a
pointer to a polymorphic class type (8.5.1.8), or
(6.6)
—
any of the immediate subexpressions (6.8.1) of e is potentially-throwing.
7
An implicitly-declared constructor for a class X, or a constructor without a noexcept-specifier that is defaulted
on its first declaration, has a potentially-throwing exception specification if and only if any of the following
constructs is potentially-throwing:
§ 18.4
391
(7.1)
—
a constructor selected by overload resolution in the implicit definition of the constructor for class X to
initialize a potentially constructed subobject, or
(7.2)
—
a subexpression of such an initialization, such as a default argument expression, or,
(7.3)
—
for a default constructor, a default member initializer.
[Note: Even though destructors for fully-constructed subobjects are invoked when an exception is thrown
during the execution of a constructor (18.2), their exception specifications do not contribute to the ex-
ception specification of the constructor, because an exception thrown from such a destructor would call
std::terminate rather than escape the constructor (18.1, 18.5.1).
— end note ]
8
The exception specification for an implicitly-declared destructor, or a destructor without a noexcept-specifier,
is potentially-throwing if and only if any of the destructors for any of its potentially constructed subobjects
is potentially throwing.
9
The exception specification for an implicitly-declared assignment operator, or an assignment-operator without
a noexcept-specifier that is defaulted on its first declaration, is potentially-throwing if and only if the invocation
of any assignment operator in the implicit definition is potentially-throwing.
10
A deallocation function (6.6.4.4.2) with no explicit noexcept-specifier has a non-throwing exception specifica-
tion.
11
The exception specification for a comparison operator (8.5.8, 8.5.9, 8.5.10) without a noexcept-specifier that
is defaulted on its first declaration is potentially-throwing if and only if the invocation of any comparison
operator in the implicit definition is potentially-throwing.
12
[ Example:
struct A {
A(int = (A(5), 0)) noexcept;
A(const A&) noexcept;
A(A&&) noexcept;
~A();
};
struct B {
B() throw();
B(const B&) = default;
// implicit exception specification is noexcept(true)
B(B&&, int = (throw Y(), 0)) noexcept;
~B() noexcept(false);
};
int n = 7;
struct D : public A, public B {
int * p = new int[n];
// D::D() potentially-throwing, as the new operator may throw bad_alloc or bad_array_new_length
// D::D(const D&) non-throwing
// D::D(D&&) potentially-throwing, as the default argument for B’s constructor may throw
// D::~D() potentially-throwing
};
Furthermore, if A::~A() were virtual, the program would be ill-formed since a function that overrides a
virtual function from a base class shall not have a potentially-throwing exception specification if the base
class function has a non-throwing exception specification.
— end example ]
13
An exception specification is considered to be needed when:
(13.1)
—
in an expression, the function is the unique lookup result or the selected member of a set of overloaded
functions (6.4, 16.3, 16.4);
(13.2)
—
the function is odr-used (6.2) or, if it appears in an unevaluated operand, would be odr-used if the
expression were potentially-evaluated;
(13.3)
—
the exception specification is compared to that of another declaration (e.g., an explicit specialization or
an overriding virtual function);
(13.4)
—
the function is defined; or
(13.5)
—
the exception specification is needed for a defaulted special member function that calls the function.
[ Note: A defaulted declaration does not require the exception specification of a base member function
§ 18.4
392
to be evaluated until the implicit exception specification of the derived function is needed, but an
explicit noexcept-specifier needs the implicit exception specification to compare against.
— end note ]
The exception specification of a defaulted special member function is evaluated as described above only when
needed; similarly, the noexcept-specifier of a specialization of a function template or member function of a
class template is instantiated only when needed.
18.5
Special functions
[except.special]
1
The function std::terminate() (18.5.1) is used by the exception handling mechanism for coping with
errors related to the exception handling mechanism itself. The function std::current_exception() (21.8.6)
and the class std::nested_exception (21.8.7) can be used by a program to capture the currently handled
exception.
18.5.1
The std::terminate() function
[except.terminate]
1
In some situations exception handling must be abandoned for less subtle error handling techniques. [ Note:
These situations are:
(1.1)
—
when the exception handling mechanism, after completing the initialization of the exception object but
before activation of a handler for the exception (18.1), calls a function that exits via an exception, or
(1.2)
—
when the exception handling mechanism cannot find a handler for a thrown exception (18.3), or
(1.3)
—
when the search for a handler (18.3) encounters the outermost block of a function with a non-throwing
exception specification (18.4), or
(1.4)
—
when the destruction of an object during stack unwinding (18.2) terminates by throwing an exception,
or
(1.5)
—
when initialization of a non-local variable with static or thread storage duration (6.8.3.3) exits via an
exception, or
(1.6)
—
when destruction of an object with static or thread storage duration exits via an exception (6.8.3.4), or
(1.7)
—
when execution of a function registered with std::atexit or std::at_quick_exit exits via an
exception (21.5), or
(1.8)
—
when a throw-expression (8.5.17) with no operand attempts to rethrow an exception and no exception
is being handled (18.1), or
(1.9)
—
when the function std::nested_exception::rethrow_nested is called for an object that has captured
no exception (21.8.7), or
(1.10)
—
when execution of the initial function of a thread exits via an exception (33.3.2.2), or
(1.11)
—
for a parallel algorithm whose ExecutionPolicy specifies such behavior (23.19.4, 23.19.5, 23.19.6), when
execution of an element access function (28.4.1) of the parallel algorithm exits via an exception (28.4.4),
or
(1.12)
—
when the destructor or the copy assignment operator is invoked on an object of type std::thread that
refers to a joinable thread (33.3.2.3, 33.3.2.4), or
(1.13)
—
when a call to a wait(), wait_until(), or wait_for() function on a condition variable (33.5.3, 33.5.4)
fails to meet a postcondition.
— end note ]
2
In such cases, std::terminate() is called (21.8.4). In the situation where no matching handler is found,
it is implementation-defined whether or not the stack is unwound before std::terminate() is called. In
the situation where the search for a handler (18.3) encounters the outermost block of a function with a
non-throwing exception specification (18.4), it is implementation-defined whether the stack is unwound,
unwound partially, or not unwound at all before std::terminate() is called. In all other situations, the
stack shall not be unwound before std::terminate() is called. An implementation is not permitted to finish
stack unwinding prematurely based on a determination that the unwind process will eventually cause a call
to std::terminate().
18.5.2
The std::uncaught_exceptions() function
[except.uncaught]
1
An exception is considered uncaught after completing the initialization of the exception object (18.1) until
completing the activation of a handler for the exception (18.3). This includes stack unwinding. If an exception
§ 18.5.2
393
is rethrown (8.5.17, 21.8.6), it is considered uncaught from the point of rethrow until the rethrown exception
is caught. The function std::uncaught_exceptions() (21.8.5) returns the number of uncaught exceptions
in the current thread.
§ 18.5.2
394
19
Preprocessing directives
[cpp]
1
A preprocessing directive consists of a sequence of preprocessing tokens that satisfies the following constraints:
The first token in the sequence is a # preprocessing token that (at the start of translation phase 4) is either
the first character in the source file (optionally after white space containing no new-line characters) or that
follows white space containing at least one new-line character. The last token in the sequence is the first
new-line character that follows the first token in the sequence.147 A new-line character ends the preprocessing
directive even if it occurs within what would otherwise be an invocation of a function-like macro.
preprocessing-file:
groupopt
group:
group-part
group group-part
group-part:
control-line
if-section
text-line
# conditionally-supported-directive
control-line:
# include
pp-tokens new-line
# define
identifier replacement-list new-line
# define
identifier lparen identifier-listopt ) replacement-list new-line
# define
identifier lparen ... ) replacement-list new-line
# define
identifier lparen identifier-list , ...
) replacement-list new-line
# undef
identifier new-line
# line
pp-tokens new-line
# error
pp-tokensopt new-line
# pragma
pp-tokensopt new-line
# new-line
if-section:
if-group elif-groupsopt else-groupopt endif-line
if-group:
# if
constant-expression new-line groupopt
# ifdef
identifier new-line groupopt
# ifndef
identifier new-line groupopt
elif-groups:
elif-group
elif-groups elif-group
elif-group:
# elif
constant-expression new-line groupopt
else-group:
# else
new-line groupopt
endif-line:
# endif
new-line
text-line:
pp-tokensopt new-line
conditionally-supported-directive:
pp-tokens new-line
lparen:
a ( character not immediately preceded by white-space
147) Thus, preprocessing directives are commonly called “lines”. These “lines” have no other syntactic significance, as all white
space is equivalent except in certain situations during preprocessing (see the # character string literal creation operator in 19.3.2,
for example).
Preprocessing directives
395
identifier-list:
identifier
identifier-list , identifier
replacement-list:
pp-tokensopt
pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
new-line:
the new-line character
2
A text line shall not begin with a # preprocessing token. A conditionally-supported-directive shall not
begin with any of the directive names appearing in the syntax. A conditionally-supported-directive is
conditionally-supported with implementation-defined semantics.
3
When in a group that is skipped (19.1), the directive syntax is relaxed to allow any sequence of preprocessing
tokens to occur between the directive name and the following new-line character.
4
The only white-space characters that shall appear between preprocessing tokens within a preprocessing
directive (from just after the introducing # preprocessing token through just before the terminating new-line
character) are space and horizontal-tab (including spaces that have replaced comments or possibly other
white-space characters in translation phase 3).
5
The implementation can process and skip sections of source files conditionally, include other source files,
and replace macros. These capabilities are called preprocessing, because conceptually they occur before
translation of the resulting translation unit.
6
The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise
stated.
[ Example: In:
#define EMPTY
EMPTY
# include <file.h>
the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does not
begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has been
replaced. — end example ]
19.1
Conditional inclusion
[cpp.cond]
defined-macro-expression:
defined identifier
defined ( identifier )
h-preprocessing-token:
any preprocessing-token other than >
h-pp-tokens:
h-preprocessing-token
h-pp-tokens h-preprocessing-token
has-include-expression:
__has_include ( < h-char-sequence > )
__has_include ( " q-char-sequence " )
__has_include ( string-literal )
__has_include ( < h-pp-tokens > )
1
The expression that controls conditional inclusion shall be an integral constant expression except that
identifiers (including those lexically identical to keywords) are interpreted as described below148 and it may
contain zero or more defined-macro-expressions and/or has-include-expressions as unary operator expressions.
2
A defined-macro-expression evaluates to 1 if the identifier is currently defined as a macro name (that is, if it
is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef
directive with the same subject identifier), 0 if it is not.
148) Because the controlling constant expression is evaluated during translation phase 4, all identifiers either are or are not
macro names — there simply are no keywords, enumeration constants, etc.
§ 19.1
396
3
The third and fourth forms of has-include-expression are considered only if neither of the first or second
forms matches, in which case the preprocessing tokens are processed just as in normal text.
4
The header or source file identified by the parenthesized preprocessing token sequence in each contained
has-include-expression is searched for as if that preprocessing token sequence were the pp-tokens in a #include
directive, except that no further macro expansion is performed. If such a directive would not satisfy the
syntactic requirements of a #include directive, the program is ill-formed. The has-include-expression
evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.
5
The #ifdef and #ifndef directives, and the defined conditional inclusion operator, shall treat __has_-
include as if it were the name of a defined macro. The identifier __has_include shall not appear in any
context not mentioned in this subclause.
6
Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling
expression) after all macro replacements have occurred shall be in the lexical form of a token (5.6).
7
Preprocessing directives of the forms
# if
constant-expression new-line groupopt
# elif
constant-expression new-line groupopt
check whether the controlling constant expression evaluates to nonzero.
8
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling
constant expression are replaced (except for those macro names modified by the defined unary operator),
just as in normal text. If the token defined is generated as a result of this replacement process or use of
the defined unary operator does not match one of the two specified forms prior to macro replacement, the
behavior is undefined.
9
After all replacements due to macro expansion and evaluations of defined-macro-expressions and has-include-
expressions have been performed, all remaining identifiers and keywords, except for true and false, are
replaced with the pp-number 0, and then each preprocessing token is converted into a token. [Note: An
alternative token (5.5) is not an identifier, even when its spelling consists entirely of letters and underscores.
Therefore it is not subject to this replacement.
— end note ]
10
The resulting tokens comprise the controlling constant expression which is evaluated according to the
rules of 8.6 using arithmetic that has at least the ranges specified in 21.3. For the purposes of this token
conversion and evaluation all signed and unsigned integer types act as if they have the same representation
as, respectively, intmax_t or uintmax_t (21.4). [ Note: Thus on an implementation where std::numeric_-
limits<int>::max() is 0x7FFF and std::numeric_limits<unsigned int>::max() is 0xFFFF, the integer
literal 0x8000 is signed and positive within a #if expression even though it is unsigned in translation phase
7
(5.2).
— end note ] This includes interpreting character literals, which may involve converting escape
sequences into execution character set members. Whether the numeric value for these character literals
matches the value obtained when an identical character literal occurs in an expression (other than within a
#if or #elif directive) is implementation-defined. [ Note: Thus, the constant expression in the following #if
directive and if statement is not guaranteed to evaluate to the same value in these two contexts:
#if ’z’ - ’a’ == 25
if (’z’ - ’a’ == 25)
— end note ] Also, whether a single-character character literal may have a negative value is implementation-
defined. Each subexpression with type bool is subjected to integral promotion before processing continues.
11
Preprocessing directives of the forms
# ifdef
identifier new-line groupopt
# ifndef
identifier new-line groupopt
check whether the identifier is or is not currently defined as a macro name. Their conditions are equivalent
to #if defined identifier and #if !defined identifier respectively.
12
Each directive’s condition is checked in order. If it evaluates to false (zero), the group that it controls is
skipped: directives are processed only through the name that determines the directive in order to keep track
of the level of nested conditionals; the rest of the directives’ preprocessing tokens are ignored, as are the other
preprocessing tokens in the group. Only the first group whose control condition evaluates to true (nonzero)
is processed; any following groups are skipped and their controlling directives are processed as if they were
in a group that is skipped. If none of the conditions evaluates to true, and there is a #else directive, the
§ 19.1
397
group controlled by the #else is processed; lacking a #else directive, all the groups until the #endif are
skipped.149
[ Example: This demonstrates a way to include a library optional facility only if it is available:
#if __has_include(<optional>)
# include <optional>
# define have_optional 1
#elif __has_include(<experimental/optional>)
# include <experimental/optional>
# define have_optional 1
# define experimental_optional 1
#else
# define have_optional 0
#endif
— end example ]
19.2
Source file inclusion
[cpp.include]
1
A #include directive shall identify a header or source file that can be processed by the implementation.
2
A preprocessing directive of the form
# include < h-char-sequence > new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence
between the < and > delimiters, and causes the replacement of that directive by the entire contents of the
header. How the places are specified or the header identified is implementation-defined.
3
A preprocessing directive of the form
# include " q-char-sequence " new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified
sequence between the " delimiters. The named source file is searched for in an implementation-defined
manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read
# include < h-char-sequence > new-line
with the identical contained sequence (including > characters, if any) from the original directive.
4
A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in
the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is
replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does
not match one of the two previous forms, the behavior is undefined.150 The method by which a sequence of
preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into
a single header name preprocessing token is implementation-defined.
5
The implementation shall provide unique mappings for sequences consisting of one or more nondigits or
digits (5.10) followed by a period (.) and a single nondigit. The first character shall not be a digit. The
implementation may ignore distinctions of alphabetical case.
6
A #include preprocessing directive may appear in a source file that has been read because of a #include
directive in another file, up to an implementation-defined nesting limit.
7
[ Note: Although an implementation may provide a mechanism for making arbitrary source files available to
the < > search, in general programmers should use the < > form for headers provided with the implementation,
and the " " form for sources outside the control of the implementation. For instance:
#include <stdio.h>
#include <unistd.h>
#include "usefullib.h"
#include "myprog.h"
149) As indicated by the syntax, a preprocessing token shall not follow a #else or #endif directive before the terminating
new-line character. However, comments may appear anywhere in a source file, including within a preprocessing directive.
150) Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in 5.2); thus,
an expansion that results in two string literals is an invalid directive.
§ 19.2
398
— end note ]
8
[ Example: This illustrates macro-replaced #include directives:
#if VERSION == 1
#define INCFILE "vers1.h"
#elif VERSION == 2
#define INCFILE "vers2.h"
// and so on
#else
#define INCFILE "versN.h"
#endif
#include INCFILE
— end example ]
19.3
Macro replacement
[cpp.replace]
1
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
ordering, spelling, and white-space separation, where all white-space separations are considered identical.
2
An identifier currently defined as an object-like macro (see below) may be redefined by another #define
preprocessing directive provided that the second definition is an object-like macro definition and the two
replacement lists are identical, otherwise the program is ill-formed. Likewise, an identifier currently defined as
a function-like macro (see below) may be redefined by another #define preprocessing directive provided that
the second definition is a function-like macro definition that has the same number and spelling of parameters,
and the two replacement lists are identical, otherwise the program is ill-formed.
3
There shall be white-space between the identifier and the replacement list in the definition of an object-like
macro.
4
If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including
those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal
the number of parameters in the macro definition. Otherwise, there shall be at least as many arguments in
the invocation as there are parameters in the macro definition (excluding the ...). There shall exist a )
preprocessing token that terminates the invocation.
5
The identifiers __VA_ARGS__ and __VA_OPT__ shall occur only in the replacement-list of a function-like
macro that uses the ellipsis notation in the parameters.
6
A parameter identifier in a function-like macro shall be uniquely declared within its scope.
7
The identifier immediately following the define is called the macro name. There is one name space for
macro names. Any white-space characters preceding or following the replacement list of preprocessing tokens
are not considered part of the replacement list for either form of macro.
8
If a # preprocessing token, followed by an identifier, occurs lexically at the point at which a preprocessing
directive could begin, the identifier is not subject to macro replacement.
9
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name151 to be replaced by the
replacement list of preprocessing tokens that constitute the remainder of the directive.152 The replacement
list is then rescanned for more macro names as specified below.
10
A preprocessing directive of the form
# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
defines a function-like macro with parameters, whose use is similar syntactically to a function call. The
parameters are specified by the optional list of identifiers, whose scope extends from their declaration in
the identifier list until the new-line character that terminates the #define preprocessing directive. Each
subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces
the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation
151) Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly
containing identifier-like subsequences (see 5.2, translation phases), they are never scanned for macro names or parameters.
152) An alternative token (5.5) is not an identifier, even when its spelling consists entirely of letters and underscores. Therefore
it is not possible to define a macro whose name is the same as that of an alternative token.
§ 19.3
399
of the macro). The replaced sequence of preprocessing tokens is terminated by the matching ) preprocessing
token, skipping intervening matched pairs of left and right parenthesis preprocessing tokens. Within the
sequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considered a
normal white-space character.
11
The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of
arguments for the function-like macro. The individual arguments within the list are separated by comma
preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate
arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise
act as preprocessing directives,153 the behavior is undefined.
12
If there is a ... immediately preceding the ) in the function-like macro definition, then the trailing arguments
(if any), including any separating comma preprocessing tokens, are merged to form a single item: the variable
arguments. The number of arguments so combined is such that, following merger, the number of arguments
is either equal to or one more than the number of parameters in the macro definition (excluding the ...).
19.3.1
Argument substitution
[cpp.subst]
1
After the arguments for the invocation of a function-like macro have been identified, argument substitution
takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed
by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained
therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely
macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
2
An identifier __VA_ARGS__ that occurs in the replacement list shall be treated as if it were a parameter, and
the variable arguments shall form the preprocessing tokens used to replace it.
3
The identifier __VA_OPT__ shall always occur as part of the token sequence __VA_OPT__(content), where
content is an arbitrary sequence of preprocessing-tokens other than __VA_OPT__, which is terminated by the
closing ) and skips intervening pairs of matching left and right parentheses. If content would be ill-formed
as the replacement list of the current function-like macro, the program is ill-formed. The token sequence
__VA_OPT__(content) shall be treated as if it were a parameter, and the preprocessing tokens used to replace
it are defined as follows. If the variable arguments consist of no tokens, the replacement consists of a single
placemarker preprocessing token (19.3.3, 19.3.4). Otherwise, the replacement consists of the results of the
expansion of content as the replacement list of the current function-like macro before rescanning and further
replacement. [ Example:
#define F(...)
f(0 __VA_OPT__(,) __VA_ARGS__)
#define G(X, ...)
f(0, X __VA_OPT__(,) __VA_ARGS__)
#define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ })
F(a, b, c)
// replaced by f(0, a, b, c)
F()
// replaced by f(0)
G(a, b, c)
// replaced by f(0, a, b, c)
G(a, )
// replaced by f(0, a)
G(a)
// replaced by f(0, a)
SDEF(foo);
// replaced by S foo;
SDEF(bar, 1, 2);
// replaced by S bar = { 1, 2 };
#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // ill-formed: ## may not appear at
// the beginning of a replacement list (19.3.3)
#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__
H2(a, b, c, d)
// replaced by ab, c, d
— end example ]
19.3.2
The # operator
[cpp.stringize]
1
Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter
as the next preprocessing token in the replacement list.
153) A conditionally-supported-directive is a preprocessing directive regardless of whether the implementation supports it.
§ 19.3.2
400
2
A character string literal is a string-literal with no prefix. If, in the replacement list, a parameter is
immediately preceded by a # preprocessing token, both are replaced by a single character string literal
preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding
argument. Each occurrence of white space between the argument’s preprocessing tokens becomes a single
space character in the character string literal. White space before the first preprocessing token and after
the last preprocessing token comprising the argument is deleted. Otherwise, the original spelling of each
preprocessing token in the argument is retained in the character string literal, except for special handling for
producing the spelling of string literals and character literals: a \ character is inserted before each " and \
character of a character literal or string literal (including the delimiting " characters). If the replacement
that results is not a valid character string literal, the behavior is undefined. The character string literal
corresponding to an empty argument is "". The order of evaluation of # and ## operators is unspecified.
19.3.3
The ## operator
[cpp.concat]
1
A ## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form
of macro definition.
2
If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ##
preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence;
however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker
preprocessing token instead.154
3
For both object-like and function-like macro invocations, before the replacement list is reexamined for more
macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an
argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing
token. Placemarker preprocessing tokens are handled specially: concatenation of two placemarkers results
in a single placemarker preprocessing token, and concatenation of a placemarker with a non-placemarker
preprocessing token results in the non-placemarker preprocessing token. If the result is not a valid preprocessing
token, the behavior is undefined. The resulting token is available for further macro replacement. The order
of evaluation of ## operators is unspecified.
[ Example: In the following fragment:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y);
// equivalent to char p[] = "x ## y";
The expansion produces, at various stages:
join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"
In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but this
new token is not the ## operator.
— end example ]
19.3.4
Rescanning and further replacement
[cpp.rescan]
1
After all parameters in the replacement list have been substituted and # and ## processing has taken place, all
placemarker preprocessing tokens are removed. Then the resulting preprocessing token sequence is rescanned,
along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
2
If the name of the macro being replaced is found during this scan of the replacement list (not including the rest
of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter
the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing
tokens are no longer available for further replacement even if they are later (re)examined in contexts in which
that macro name preprocessing token would otherwise have been replaced.
3
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing
directive even if it resembles one, but all pragma unary operator expressions within it are then processed as
specified in 19.9 below.
154) Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within
translation phase 4.
§ 19.3.4
401
19.3.5
Scope of macro definitions
[cpp.scope]
1
A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered
or (if none is encountered) until the end of the translation unit. Macro definitions have no significance after
translation phase 4.
2
A preprocessing directive of the form
# undef identifier new-line
causes the specified identifier no longer to be defined as a macro name. It is ignored if the specified identifier
is not currently defined as a macro name.
3
[ Example: The simplest use of this facility is to define a “manifest constant”, as in
#define TABSIZE 100
int table[TABSIZE];
— end example ]
4
[ Example: The following defines a function-like macro whose value is the maximum of its arguments. It has
the advantages of working for any compatible types of the arguments and of generating in-line code without
the overhead of function calling. It has the disadvantages of evaluating one or the other of its arguments a
second time (including side effects) and generating more code than a function if invoked several times. It also
cannot have its address taken, as it has none.
#define max(a, b) ((a) > (b) ? (a) : (b))
The parentheses ensure that the arguments and the resulting expression are bound properly.
— end example ]
5
[ Example: To illustrate the rules for redefinition and reexamination, the sequence
#define x
3
#define f(a)
f(x * (a))
#undef x
#define x
2
#define g
f
#define z
z[0]
#define h
g(~
#define m(a)
a(w)
#define w
0,1
#define t(a)
a
#define p()
int
#define q(x)
x
#define r(x,y)
x ## y
#define str(x)
# x
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
results in
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };
— end example ]
6
[ Example: To illustrate the rules for creating character string literals and concatenating tokens, the sequence
#define str(s)
# s
#define xstr(s)
str(s)
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
x ## s, x ## t)
#define INCFILE(n) vers ## n
#define glue(a, b) a ## b
#define xglue(a, b) glue(a, b)
#define HIGHLOW
"hello"
#define LOW
LOW ", world"
§ 19.3.5
402
debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", ’\4’)
// this goes away
== 0) str(: @\n), s);
#include xstr(INCFILE(2).h)
glue(HIGH, LOW);
xglue(HIGH, LOW)
results in
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", ’\\4’) == 0" ": @\n", s);
#include "vers2.h"
(after macro replacement, before file access)
"hello";
"hello" ", world"
or, after concatenation of the character string literals,
printf("x1= %d, x2= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", ’\\4’) == 0: @\n", s);
#include "vers2.h"
(after macro replacement, before file access)
"hello";
"hello, world"
Space around the # and ## tokens in the macro definition is optional.
— end example ]
7
[ Example: To illustrate the rules for placemarker preprocessing tokens, the sequence
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
t(10,,), t(,11,), t(,,12), t(,,) };
results in
int j[] = { 123, 45, 67, 89,
10, 11, 12, };
— end example ]
8
[ Example: To demonstrate the redefinition rules, the following sequence is valid.
#define OBJ_LIKE
(1-1)
#define OBJ_LIKE
/* white space */ (1-1) /* other */
#define FUNC_LIKE(a)
( a )
#define FUNC_LIKE( a )(
/* note the white space */ \
a /* other stuff on this line
*/ )
But the following redefinitions are invalid:
#define OBJ_LIKE
(0)
// different token sequence
#define OBJ_LIKE
(1 - 1)
// different white space
#define FUNC_LIKE(b) ( a )
// different parameter usage
#define FUNC_LIKE(b) ( b )
// different parameter spelling
— end example ]
9
[ Example: Finally, to show the variable argument list macro facilities:
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define showlist(...) puts(#__VA_ARGS__)
#define report(test, ...) ((test) ? puts(#test) : printf(__VA_ARGS__))
debug("Flag");
debug("X = %d\n", x);
showlist(The first, second, and third items.);
report(x>y, "x is %d but y is %d", x, y);
results in
fprintf(stderr, "Flag");
fprintf(stderr, "X = %d\n", x);
puts("The first, second, and third items.");
((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y));
— end example ]
§ 19.3.5
403
19.4
Line control
[cpp.line]
1
The string literal of a #line directive, if present, shall be a character string literal.
2
The line number of the current source line is one greater than the number of new-line characters read or
introduced in translation phase 1 (5.2) while processing the source file to the current token.
3
A preprocessing directive of the form
# line digit-sequence new-line
causes the implementation to behave as if the following sequence of source lines begins with a source line that
has a line number as specified by the digit sequence (interpreted as a decimal integer). If the digit sequence
specifies zero or a number greater than 2147483647, the behavior is undefined.
4
A preprocessing directive of the form
# line digit-sequence " s-char-sequenceopt " new-line
sets the presumed line number similarly and changes the presumed name of the source file to be the contents
of the character string literal.
5
A preprocessing directive of the form
# line pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after line on the
directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by
its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match
one of the two previous forms, the behavior is undefined; otherwise, the result is processed as appropriate.
19.5
Error directive
[cpp.error]
1
A preprocessing directive of the form
# error pp-tokensopt new-line
causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing
tokens, and renders the program ill-formed.
19.6
Pragma directive
[cpp.pragma]
1
A preprocessing directive of the form
# pragma pp-tokensopt new-line
causes the implementation to behave in an implementation-defined manner. The behavior might cause
translation to fail or cause the translator or the resulting program to behave in a non-conforming manner.
Any pragma that is not recognized by the implementation is ignored.
19.7
Null directive
[cpp.null]
1
A preprocessing directive of the form
# new-line
has no effect.
19.8
Predefined macro names
[cpp.predefined]
1
The following macro names shall be defined by the implementation:
__cplusplus
The integer literal 201703L.155
__DATE__
The date of translation of the source file: a character string literal of the form "Mmm dd yyyy", where
the names of the months are the same as those generated by the asctime function, and the first
character of dd is a space character if the value is less than 10. If the date of translation is not available,
an implementation-defined valid date shall be supplied.
155) It is intended that future versions of this International Standard will replace the value of this macro with a greater value.
Non-conforming compilers should use a value with at most five decimal digits.
§ 19.8
404
__FILE__
The presumed name of the current source file (a character string literal).156
__LINE__
The presumed line number (within the current source file) of the current source line (an integer
literal).157
__STDC_HOSTED__
The integer literal 1 if the implementation is a hosted implementation or the integer literal 0 if it is not.
__STDCPP_DEFAULT_NEW_ALIGNMENT__
An integer literal of type std::size_t whose value is the alignment guaranteed by a call to operator
new(std::size_t) or operator new[](std::size_t). [ Note: Larger alignments will be passed to
operator new(std::size_t, std::align_val_t), etc. (8.5.2.4).
— end note ]
__TIME__
The time of translation of the source file: a character string literal of the form "hh:mm:ss" as in the time
generated by the asctime function. If the time of translation is not available, an implementation-defined
valid time shall be supplied.
2
The following macro names are conditionally defined by the implementation:
__STDC__
Whether __STDC__ is predefined and if so, what its value is, are implementation-defined.
__STDC_MB_MIGHT_NEQ_WC__
The integer literal 1, intended to indicate that, in the encoding for wchar_t, a member of the basic
character set need not have a code value equal to its value when used as the lone character in an
ordinary character literal.
__STDC_VERSION__
Whether __STDC_VERSION__ is predefined and if so, what its value is, are implementation-defined.
__STDC_ISO_10646__
An integer literal of the form yyyymmL (for example, 199712L). If this symbol is defined, then every
character in the Unicode required set, when stored in an object of type wchar_t, has the same value as
the short identifier of that character. The Unicode required set consists of all the characters that are
defined by ISO/IEC 10646, along with all amendments and technical corrigenda as of the specified year
and month.
__STDCPP_STRICT_POINTER_SAFETY__
Defined, and has the value integer literal 1, if and only if the implementation has strict pointer
safety (6.6.4.4.3).
__STDCPP_THREADS__
Defined, and has the value integer literal 1, if and only if a program can have more than one thread of
execution (6.8.2).
3
The values of the predefined macros (except for __FILE__ and __LINE__) remain constant throughout the
translation unit.
4
If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a #define
or a #undef preprocessing directive, the behavior is undefined. Any other predefined macro names shall
begin with a leading underscore followed by an uppercase letter or a second underscore.
156) The presumed source file name can be changed by the #line directive.
157) The presumed line number can be changed by the #line directive.
§ 19.8
405
19.9
Pragma operator
[cpp.pragma.op]
1
A unary operator expression of the form:
_Pragma ( string-literal )
is processed as follows: The string literal is destringized by deleting the L prefix, if present, deleting the
leading and trailing double-quotes, replacing each escape sequence \" by a double-quote, and replacing
each escape sequence \\ by a single backslash. The resulting sequence of characters is processed through
translation phase 3 to produce preprocessing tokens that are executed as if they were the pp-tokens in a
pragma directive. The original four preprocessing tokens in the unary operator expression are removed.
2
[ Example:
#pragma listing on "..\listing.dir"
can also be expressed as:
_Pragma ( "listing on \"..\\listing.dir\"" )
The latter form is processed in the same way whether it appears literally as shown, or results from macro
replacement, as in:
#define LISTING(x) PRAGMA(listing on #x)
#define PRAGMA(x) _Pragma(#x)
LISTING( ..\listing.dir )
— end example ]
§ 19.9
406
20
Library introduction
[library]
20.1
General
[library.general]
1
This Clause describes the contents of the C++ standard library, how a well-formed C++ program makes use
of the library, and how a conforming implementation may provide the entities in the library.
2
The following subclauses describe the definitions (20.3), method of description (20.4), and organization (20.5.1)
of the library. 20.5, Clause 21 through Clause 33, and Annex D specify the contents of the library, as well as
library requirements and constraints on both well-formed C++ programs and conforming implementations.
3
Detailed specifications for each of the components in the library are in Clause 21-Clause 33, as shown in
Table 15.
Table 15 — Library categories
Clause
Category
Clause 21
Language support library
Clause 22
Diagnostics library
Clause 23
General utilities library
Clause 24
Strings library
Clause 25
Localization library
Clause 26
Containers library
Clause 27
Iterators library
Clause 28
Algorithms library
Clause 29
Numerics library
Clause 30
Input/output library
Clause 31
Regular expressions library
Clause 32
Atomic operations library
Clause 33
Thread support library
4
The language support library (Clause 21) provides components that are required by certain parts of the C++
language, such as memory allocation (8.5.2.4, 8.5.2.5) and exception processing (Clause 18).
5
The diagnostics library (Clause 22) provides a consistent framework for reporting errors in a C++ program,
including predefined exception classes.
6
The general utilities library (Clause 23) includes components used by other library elements, such as a
predefined storage allocator for dynamic storage management (6.6.4.4), and components used as infrastructure
in C++ programs, such as tuples, function wrappers, and time facilities.
7
The strings library (Clause 24) provides support for manipulating text represented as sequences of type char,
sequences of type char16_t, sequences of type char32_t, sequences of type wchar_t, and sequences of any
other character-like type.
8
The localization library (Clause 25) provides extended internationalization support for text processing.
9
The containers (Clause 26), iterators (Clause 27), and algorithms (Clause 28) libraries provide a C++ program
with access to a subset of the most widely used algorithms and data structures.
10
The numerics library (Clause 29) provides numeric algorithms and complex number components that extend
support for numeric processing. The valarray component provides support for n-at-a-time processing,
potentially implemented as parallel operations on platforms that support such processing. The random
number component provides facilities for generating pseudo-random numbers.
11
The input/output library (Clause 30) provides the iostream components that are the primary mechanism
for C++ program input and output. They can be used with other elements of the library, particularly strings,
locales, and iterators.
12
The regular expressions library (Clause 31) provides regular expression matching and searching.
§ 20.1
407
13
The atomic operations library (Clause 32) allows more fine-grained concurrent access to shared data than is
possible with locks.
14
The thread support library (Clause 33) provides components to create and manage threads, including mutual
exclusion and interthread communication.
20.2
The C standard library
[library.c]
1
The C++ standard library also makes available the facilities of the C standard library, suitably adjusted to
ensure static type safety.
2
The descriptions of many library functions rely on the C standard library for the semantics of those functions.
In some cases, the signatures specified in this document may be different from the signatures in the C
standard library, and additional overloads may be declared in this document, but the behavior and the
preconditions (including any preconditions implied by the use of an ISO C restrict qualifier) are the same
unless otherwise stated.
20.3
Definitions
[definitions]
1
[ Note: Clause 3 defines additional terms used elsewhere in this document.
— end note ]
20.3.1
[defns.arbitrary.stream]
arbitrary-positional stream
stream (described in Clause 30) that can seek to any integral position within the length of the stream
[ Note 1 to entry: Every arbitrary-positional stream is also a repositional stream.
— end note ]
20.3.2
[defns.character]
character
〈Clause 24, Clause 25, Clause 30, and Clause 31〉 object which, when treated sequentially, can represent text
[ Note 1 to entry: The term does not mean only char, char16_t, char32_t, and wchar_t objects, but any
value that can be represented by a type that provides the definitions specified in these Clauses.
— end note ]
20.3.3
[defns.character.container]
character container type
class or a type used to represent a character
[ Note 1 to entry: It is used for one of the template parameters of the string, iostream, and regular expression
class templates.
— end note ]
20.3.4
[defns.comparison]
comparison function
operator function (16.5) for any of the equality (8.5.10) or relational (8.5.9) operators
20.3.5
[defns.component]
component
group of library entities directly related as members, parameters, or return types
[ Note 1 to entry: For example, the class template basic_string and the non-member function templates
that operate on strings are referred to as the string component.
— end note ]
20.3.6
[defns.const.subexpr]
constant subexpression
expression whose evaluation as subexpression of a conditional-expression CE (8.5.16) would not prevent CE
from being a core constant expression (8.6)
20.3.7
[defns.deadlock]
deadlock
situation wherein one or more threads are unable to continue execution because each is blocked waiting for
one or more of the others to satisfy some condition
20.3.8
[defns.default.behavior.impl]
default behavior
〈implementation〉 specific behavior provided by the implementation, within the scope of the required behavior
§ 20.3.8
408
20.3.9
[defns.default.behavior.func]
default behavior
〈specification〉 description of replacement function and handler function semantics
20.3.10
[defns.direct-non-list-init]
direct-non-list-initialization
direct-initialization (11.6) that is not list-initialization (11.6.4)
20.3.11
[defns.handler]
handler function
non-reserved function whose definition may be provided by a C++ program
[Note 1 to entry: A C++ program may designate a handler function at various points in its execution
by supplying a pointer to the function when calling any of the library functions that install handler
functions (Clause 21).
— end note ]
20.3.12
[defns.iostream.templates]
iostream class templates
templates, defined in Clause 30, that take two template arguments
[Note 1 to entry: The arguments are named charT and traits. The argument charT is a character
container class, and the argument traits is a class which defines additional characteristics and functions of
the character type represented by charT necessary to implement the iostream class templates.
— end note ]
20.3.13
[defns.modifier]
modifier function
class member function (12.2.1) other than a constructor, assignment operator, or destructor that alters the
state of an object of the class
20.3.14
[defns.move.assign]
move assignment
assignment of an rvalue of some object type to a modifiable lvalue of the same type
20.3.15
[defns.move.constr]
move construction
direct-initialization of an object of some type with an rvalue of the same type
20.3.16
[defns.ntcts]
NTCTS
sequence of values that have character type that precede the terminating null character type value charT()
20.3.17
[defns.observer]
observer function
class member function (12.2.1) that accesses the state of an object of the class but does not alter that state
[ Note 1 to entry: Observer functions are specified as const member functions (12.2.2.1).
— end note ]
20.3.18
[defns.referenceable]
referenceable type
type that is either an object type, a function type that does not have cv-qualifiers or a ref-qualifier, or a
reference type
[ Note 1 to entry: The term describes a type to which a reference can be created, including reference types.
— end note ]
20.3.19
[defns.replacement]
replacement function
non-reserved function whose definition is provided by a C++ program
[Note 1 to entry: Only one definition for such a function is in effect for the duration of the program’s
execution, as the result of creating the program (5.2) and resolving the definitions of all translation units (6.5).
— end note ]
§ 20.3.19
409
20.3.20
[defns.repositional.stream]
repositional stream
stream (described in Clause 30) that can seek to a position that was previously encountered
20.3.21
[defns.required.behavior]
required behavior
description of replacement function and handler function semantics applicable to both the behavior provided
by the implementation and the behavior of any such function definition in the program
[Note 1 to entry: If such a function defined in a C++ program fails to meet the required behavior when it
executes, the behavior is undefined.
— end note ]
20.3.22
[defns.reserved.function]
reserved function
function, specified as part of the C++ standard library, that is defined by the implementation
[ Note 1 to entry: If a C++ program provides a definition for any reserved function, the results are undefined.
— end note ]
20.3.23
[defns.stable]
stable algorithm
algorithm that preserves, as appropriate to the particular algorithm, the order of elements
[ Note 1 to entry: Requirements for stable algorithms are given in 20.5.5.7.
— end note ]
20.3.24
[defns.traits]
traits class
class that encapsulates a set of types and functions necessary for class templates and function templates to
manipulate objects of types for which they are instantiated
20.3.25
[defns.valid]
valid but unspecified state
value of an object that is not specified except that the object’s invariants are met and operations on the
object behave as specified for its type
[Example: If an object x of type std::vector<int> is in a valid but unspecified state, x.empty() can be
called unconditionally, and x.front() can be called only if x.empty() returns false.
— end example ]
20.4
Method of description (Informative)
[description]
1
This subclause describes the conventions used to specify the C++ standard library.
20.4.1 describes the
structure of the normative Clause 21 through Clause 33 and Annex D. 20.4.2 describes other editorial
conventions.
20.4.1
Structure of each clause
[structure]
20.4.1.1
Elements
[structure.elements]
1
Each library clause contains the following elements, as applicable:158
(1.1)
—
Summary
(1.2)
—
Requirements
(1.3)
—
Detailed specifications
(1.4)
—
References to the C standard library
20.4.1.2
Summary
[structure.summary]
1
The Summary provides a synopsis of the category, and introduces the first-level subclauses. Each subclause
also provides a summary, listing the headers specified in the subclause and the library entities provided in
each header.
2
The contents of the summary and the detailed specifications include:
(2.1)
—
macros
158) To save space, items that do not apply to a Clause are omitted. For example, if a Clause does not specify any requirements,
there will be no “Requirements” subclause.
§ 20.4.1.2
410
(2.2)
—
values
(2.3)
—
types
(2.4)
—
classes and class templates
(2.5)
—
functions and function templates
(2.6)
—
objects
20.4.1.3
Requirements
[structure.requirements]
1
Requirements describe constraints that shall be met by a C++ program that extends the standard library.
Such extensions are generally one of the following:
(1.1)
—
Template arguments
(1.2)
—
Derived classes
(1.3)
—
Containers, iterators, and algorithms that meet an interface convention
2
The string and iostream components use an explicit representation of operations required of template
arguments. They use a class template char_traits to define these constraints.
3
Interface convention requirements are stated as generally as possible. Instead of stating “class X has to define
a member function operator++()”, the interface requires “for any object x of class X, ++x is defined”. That
is, whether the operator is a member is unspecified.
4
Requirements are stated in terms of well-defined expressions that define valid terms of the types that satisfy
the requirements. For every set of well-defined expression requirements there is a table that specifies an initial
set of the valid expressions and their semantics. Any generic algorithm (Clause 28) that uses the well-defined
expression requirements is described in terms of the valid expressions for its template type parameters.
5
Template argument requirements are sometimes referenced by name. See 20.4.2.1.
6
In some cases the semantic requirements are presented as C++ code. Such code is intended as a specification
of equivalence of a construct to another construct, not necessarily as the way the construct must be
implemented.159
20.4.1.4
Detailed specifications
[structure.specifications]
1
The detailed specifications each contain the following elements:
(1.1)
—
name and brief description
(1.2)
—
synopsis (class definition or function declaration, as appropriate)
(1.3)
—
restrictions on template arguments, if any
(1.4)
—
description of class invariants
(1.5)
—
description of function semantics
2
Descriptions of class member functions follow the order (as appropriate):160
(2.1)
—
constructor(s) and destructor
(2.2)
—
copying, moving & assignment functions
(2.3)
—
comparison functions
(2.4)
—
modifier functions
(2.5)
—
observer functions
(2.6)
—
operators and other non-member functions
3
Descriptions of function semantics contain the following elements (as appropriate):161
(3.1)
—
Requires: the preconditions for calling the function
(3.2)
—
Effects: the actions performed by the function
(3.3)
—
Synchronization: the synchronization operations (6.8.2) applicable to the function
159) Although in some cases the code given is unambiguously the optimum implementation.
160) To save space, items that do not apply to a class are omitted. For example, if a class does not specify any comparison
functions, there will be no “Comparison functions” subclause.
161) To save space, items that do not apply to a function are omitted. For example, if a function does not specify any further
preconditions, there will be no Requires: paragraph.
§ 20.4.1.4
411
|
|