|
|
|
5.13.8
User-defined literals
[lex.ext]
user-defined-literal:
user-defined-integer-literal
user-defined-floating-literal
user-defined-string-literal
user-defined-character-literal
user-defined-integer-literal:
decimal-literal ud-suffix
octal-literal ud-suffix
hexadecimal-literal ud-suffix
binary-literal ud-suffix
user-defined-floating-literal:
fractional-constant exponent-partopt ud-suffix
digit-sequence exponent-part ud-suffix
hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix
hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix
user-defined-string-literal:
string-literal ud-suffix
user-defined-character-literal:
character-literal ud-suffix
ud-suffix:
identifier
1
If a token matches both user-defined-literal and another literal kind, it is treated as the latter. [Example:
123_km is a user-defined-literal, but 12LL is an integer-literal.
— end example ] The syntactic non-terminal
preceding the ud-suffix in a user-defined-literal is taken to be the longest sequence of characters that could
match that non-terminal.
2
A user-defined-literal is treated as a call to a literal operator or literal operator template (16.5.8). To
determine the form of this call for a given user-defined-literal L with ud-suffix X, the literal-operator-id whose
literal suffix identifier is X is looked up in the context of L using the rules for unqualified name lookup (6.4.1).
Let S be the set of declarations found by this lookup. S shall not be empty.
3
If L is a user-defined-integer-literal, let n be the literal without its ud-suffix. If S contains a literal operator
with parameter type unsigned long long, the literal L is treated as a call of the form
operator "" X (n ULL)
Otherwise, S shall contain a raw literal operator or a literal operator template (16.5.8) but not both. If S
contains a raw literal operator, the literal L is treated as a call of the form
operator "" X ("n ")
Otherwise (S contains a literal operator template), L is treated as a call of the form
operator "" X <’c1’, ’c2’, ... ’ck ’>()
where n is the source character sequence c1c2...ck . [ Note: The sequence c1c2...ck can only contain characters
from the basic source character set.
— end note ]
4
If L is a user-defined-floating-literal, let f be the literal without its ud-suffix. If S contains a literal operator
with parameter type long double, the literal L is treated as a call of the form
operator "" X (f L)
Otherwise, S shall contain a raw literal operator or a literal operator template (16.5.8) but not both. If S
contains a raw literal operator, the literal L is treated as a call of the form
operator "" X ("f ")
Otherwise (S contains a literal operator template), L is treated as a call of the form
operator "" X <’c1’, ’c2’, ... ’ck ’>()
where f is the source character sequence c1c2...ck . [ Note: The sequence c1c2...ck can only contain characters
from the basic source character set.
— end note ]
5
If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of
code units in str (i.e., its length excluding the terminating null character). The literal L is treated as a call
of the form
§ 5.13.8
22
operator "" X (str , len )
6
If L is a user-defined-character-literal, let ch be the literal without its ud-suffix. S shall contain a literal
operator (16.5.8) whose only parameter has the type of ch and the literal L is treated as a call of the form
operator "" X (ch )
7
[ Example:
long double operator "" _w(long double);
std::string operator "" _w(const char16_t*, std::size_t);
unsigned operator "" _w(const char*);
int main() {
1.2_w;
// calls operator "" _w(1.2L)
u"one"_w;
// calls operator "" _w(u"one", 3)
12_w;
// calls operator "" _w("12")
"two"_w;
// error: no applicable literal operator
}
— end example ]
8
In translation phase 6 (5.2), adjacent string literals are concatenated and user-defined-string-literals are
considered string literals for that purpose. During concatenation, ud-suffixes are removed and ignored and the
concatenation process occurs as described in 5.13.5. At the end of phase 6, if a string literal is the result of a
concatenation involving at least one user-defined-string-literal, all the participating user-defined-string-literals
shall have the same ud-suffix and that suffix is applied to the result of the concatenation.
9
[ Example:
int main() {
L"A" "B" "C"_x; // OK: same as L"ABC"_x
"P"_x "Q" "R"_y;// error: two different ud-suffixes
}
— end example ]
§ 5.13.8
23
6
Basic concepts
[basic]
1
[Note: This Clause presents the basic concepts of the C++ language. It explains the difference between an
object and a name and how they relate to the value categories for expressions. It introduces the concepts
of a declaration and a definition and presents C++’s notion of type, scope, linkage, and storage duration.
The mechanisms for starting and terminating a program are discussed. Finally, this Clause presents the
fundamental types of the language and lists the ways of constructing compound types from these. — end
note ]
2
[ Note: This Clause does not cover concepts that affect only a single part of the language. Such concepts are
discussed in the relevant Clauses.
— end note ]
3
An entity is a value, object, reference, structured binding, function, enumerator, type, class member, bit-field,
template, template specialization, namespace, or parameter pack.
4
A name is a use of an identifier (5.10), operator-function-id (16.5), literal-operator-id (16.5.8), conversion-
function-id (15.3.2), or template-id (17.2) that denotes an entity or label (9.6.4, 9.1).
5
Every name that denotes an entity is introduced by a declaration. Every name that denotes a label is
introduced either by a goto statement (9.6.4) or a labeled-statement (9.1).
6
A variable is introduced by the declaration of a reference other than a non-static data member or of an
object. The variable’s name, if any, denotes the reference or object.
7
A local entity is a variable with automatic storage duration (6.6.4.3), a structured binding (11.5) whose
corresponding variable is such an entity, or the *this object (8.4.2).
8
Some names denote types or templates. In general, whenever a name is encountered it is necessary to
determine whether that name denotes one of these entities before continuing to parse the program that
contains it. The process that determines this is called name lookup (6.4).
9
Two names are the same if
(9.1)
—
they are identifier s composed of the same character sequence, or
(9.2)
—
they are operator-function-ids formed with the same operator, or
(9.3)
—
they are conversion-function-ids formed with the same type, or
(9.4)
—
they are template-ids that refer to the same class, function, or variable (17.5), or
(9.5)
—
they are the names of literal operators (16.5.8) formed with the same literal suffix identifier.
10
A name used in more than one translation unit can potentially refer to the same entity in these translation
units depending on the linkage (6.5) of the name specified in each translation unit.
6.1
Declarations and definitions
[basic.def]
1
A declaration (Clause 10) may introduce one or more names into a translation unit or redeclare names
introduced by previous declarations. If so, the declaration specifies the interpretation and attributes of these
names. A declaration may also have effects including:
(1.1)
—
a static assertion (Clause 10),
(1.2)
—
controlling template instantiation (17.8.2),
(1.3)
—
guiding template argument deduction for constructors (17.10),
(1.4)
—
use of attributes (Clause 10), and
(1.5)
—
nothing (in the case of an empty-declaration).
2
A declaration is a definition unless
(2.1)
—
it declares a function without specifying the function’s body (11.4),
(2.2)
—
it contains the extern specifier (10.1.1) or a linkage-specification21 (10.5) and neither an initializer nor
a function-body,
21) Appearing inside the brace-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a
definition.
§ 6.1
24
(2.3)
—
it declares a non-inline static data member in a class definition (12.2, 12.2.3),
(2.4)
—
it declares a static data member outside a class definition and the variable was defined within the class
with the constexpr specifier (this usage is deprecated; see D.1),
(2.5)
—
it is a class name declaration (12.1),
(2.6)
—
it is an opaque-enum-declaration (10.2),
(2.7)
—
it is a template-parameter (17.1),
(2.8)
—
it is a parameter-declaration (11.3.5) in a function declarator that is not the declarator of a function-
definition,
(2.9)
—
it is a typedef declaration (10.1.3),
(2.10)
—
it is an alias-declaration (10.1.3),
(2.11)
—
it is a using-declaration (10.3.3),
(2.12)
—
it is a deduction-guide (17.10),
(2.13)
—
it is a static_assert-declaration (Clause 10),
(2.14)
—
it is an attribute-declaration (Clause 10),
(2.15)
—
it is an empty-declaration (Clause 10),
(2.16)
—
it is a using-directive (10.3.4),
(2.17)
—
it is an explicit instantiation declaration (17.8.2), or
(2.18)
—
it is an explicit specialization (17.8.3) whose declaration is not a definition.
[ Example: All but one of the following are definitions:
int a;
// defines a
extern const int c = 1;
// defines c
int f(int x) { return x+a; }
// defines f and defines x
struct S { int a; int b; };
// defines S, S::a, and S::b
struct X {
// defines X
int x;
// defines non-static data member x
static int y;
// declares static data member y
X(): x(0) { }
// defines a constructor of X
};
int X::y = 1;
// defines X::y
enum { up, down };
// defines up and down
namespace N { int d; }
// defines N and N::d
namespace N1 = N;
// defines N1
X anX;
// defines anX
whereas these are just declarations:
extern int a;
// declares a
extern const int c;
// declares c
int f(int);
// declares f
struct S;
// declares S
typedef int Int;
// declares Int
extern X anotherX;
// declares anotherX
using N::d;
// declares d
— end example ]
3
[Note: In some circumstances, C++ implementations implicitly define the default constructor (15.1), copy
constructor (15.8), move constructor (15.8), copy assignment operator (15.8), move assignment operator (15.8),
or destructor (15.4) member functions.
— end note ] [ Example: Given
#include <string>
struct C {
std::string s;
// std::string is the standard library class (Clause 24)
};
int main() {
C a;
§ 6.1
25
C b = a;
b = a;
}
the implementation will implicitly define functions to make the definition of C equivalent to
struct C {
std::string s;
C() : s() { }
C(const C& x): s(x.s) { }
C(C&& x): s(static_cast<std::string&&>(x.s)) { }
//
: s(std::move(x.s)) { }
C& operator=(const C& x) { s = x.s; return *this; }
C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; }
//
{ s = std::move(x.s); return *this; }
~C() { }
};
— end example ]
4
[ Note: A class name can also be implicitly declared by an elaborated-type-specifier (10.1.7.3).
— end note ]
5
A program is ill-formed if the definition of any object gives the object an incomplete type (6.7).
6.2
One-definition rule
[basic.def.odr]
1
No translation unit shall contain more than one definition of any variable, function, class type, enumeration
type, or template.
2
An expression is potentially evaluated unless it is an unevaluated operand (8.2) or a subexpression thereof.
The set of potential results of an expression e is defined as follows:
(2.1)
—
If e is an id-expression (8.4.4), the set contains only e.
(2.2)
—
If e is a subscripting operation (8.5.1.1) with an array operand, the set contains the potential results of
that operand.
(2.3)
—
If e is a class member access expression (8.5.1.5), the set contains the potential results of the object
expression.
(2.4)
—
If e is a pointer-to-member expression (8.5.4) whose second operand is a constant expression, the set
contains the potential results of the object expression.
(2.5)
—
If e has the form (e1), the set contains the potential results of e1.
(2.6)
—
If e is a glvalue conditional expression (8.5.16), the set is the union of the sets of potential results of
the second and third operands.
(2.7)
—
If e is a comma expression (8.5.19), the set contains the potential results of the right operand.
(2.8)
—
Otherwise, the set is empty.
[ Note: This set is a (possibly-empty) set of id-expressions, each of which is either e or a subexpression of e.
[ Example: In the following example, the set of potential results of the initializer of n contains the first S::x
subexpression, but not the second S::x subexpression.
struct S { static const int x = 0; };
const int &f(const int &r);
int n = b ? (1, S::x)
// S::x is not odr-used here
: f(S::x);
// S::x is odr-used here, so a definition is required
— end example ]
— end note ]
3
A function is named by an expression as follows:
(3.1)
—
A function whose name appears in an expression is named by that expression if it is the unique lookup
result or the selected member of a set of overloaded functions (6.4, 16.3, 16.4), unless it is a pure
virtual function and either its name is not explicitly qualified or the expression forms a pointer to
member (8.5.2.1). [ Note: This covers taking the address of functions (7.3, 8.5.2.1), calls to named
functions (8.5.1.2), operator overloading (Clause 16), user-defined conversions (15.3.2), allocation
functions for placement new-expressions (8.5.2.4), as well as non-default initialization (11.6). A
constructor selected to copy or move an object of class type is considered to be named by an expression
even if the call is actually elided by the implementation (15.8).
— end note ]
§ 6.2
26
(3.2)
—
An allocation or deallocation function for a class is named by a new-expression as specified in 8.5.2.4
and 15.5.
—
(3.3)
A deallocation function for a class is named by a delete expression as specified in 8.5.2.5 and 15.5.
4
A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying
the lvalue-to-rvalue conversion (7.1) to x yields a constant expression (8.6) that does not invoke any non-trivial
functions and, if x is an object, ex is an element of the set of potential results of an expression e, where
either the lvalue-to-rvalue conversion (7.1) is applied to e, or e is a discarded-value expression (8.2).
5
A structured binding is odr-used if it appears as a potentially-evaluated expression.
6
*this is odr-used if this appears as a potentially-evaluated expression (including as the result of the implicit
transformation in the body of a non-static member function (12.2.2)).
7
A virtual member function is odr-used if it is not pure. A function is odr-used if it is named by a potentially-
evaluated expression. A non-placement allocation or deallocation function for a class is odr-used by the
definition of a constructor of that class. A non-placement deallocation function for a class is odr-used by the
definition of the destructor of that class, or by being selected by the lookup at the point of definition of a
virtual destructor (15.4).22
8
An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-
assignment function for another class as specified in 15.8. A constructor for a class is odr-used as specified
in 11.6. A destructor for a class is odr-used if it is potentially invoked (15.4).
9
A local entity (Clause 6) is odr-usable in a declarative region (6.3.1) if:
(9.1)
—
the local entity is either not *this, or an enclosing class or non-lambda function parameter scope exists
and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member
function, and
(9.2)
—
for each intervening declarative region (6.3.1) between the point at which the entity is introduced
and the region (where *this is considered to be introduced within the innermost enclosing class or
non-lambda function definition scope), either:
(9.2.1)
—
the declarative region is a block scope, or
(9.2.2)
—
the declarative region is the function parameter scope of a lambda-expression that has a simple-
capture naming the entity or has a capture-default.
If a local entity is odr-used in a declarative region in which it is not odr-usable, the program is ill-formed.
[ Example:
void f(int n) {
[] { n = 1; };
// error, n is not odr-usable due to intervening lambda-expression
struct A {
void f() { n = 2; }
// error, n is not odr-usable due to intervening function definition scope
};
void g(int = n);
// error, n is not odr-usable due to intervening function parameter scope
[&] { [n]{ return n; }; };
// OK
}
— end example ]
10
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in
that program outside of a discarded statement (9.4.1); no diagnostic required. The definition can appear
explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is
implicitly defined (see 15.1, 15.4 and 15.8). An inline function or variable shall be defined in every translation
unit in which it is odr-used outside of a discarded statement.
11
Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the
class type to be complete. [ Example: The following complete translation unit is well-formed, even though it
never defines X:
struct X;
// declare X as a struct type
struct X* x1;
// use X in pointer formation
X* x2;
// use X in pointer formation
22) An implementation is not required to call allocation and deallocation functions from constructors or destructors; however,
this is a permissible implementation technique.
§ 6.2
27
— end example ] [ Note: The rules for declarations and expressions describe in which contexts complete class
types are required. A class type T must be complete if:
(11.1)
—
an object of type T is defined (6.1), or
(11.2)
—
a non-static class data member of type T is declared (12.2), or
(11.3)
—
T is used as the allocated type or array element type in a new-expression (8.5.2.4), or
(11.4)
—
an lvalue-to-rvalue conversion is applied to a glvalue referring to an object of type T (7.1), or
(11.5)
—
an expression is converted (either implicitly or explicitly) to type T (Clause 7, 8.5.1.3, 8.5.1.7, 8.5.1.9,
8.5.3), or
(11.6)
—
an expression that is not a null pointer constant, and has type other than cv void*, is converted to the
type pointer to T or reference to T using a standard conversion (Clause 7), a dynamic_cast (8.5.1.7) or
a static_cast (8.5.1.9), or
(11.7)
—
a class member access operator is applied to an expression of type T (8.5.1.5), or
(11.8)
—
the typeid operator (8.5.1.8) or the sizeof operator (8.5.2.3) is applied to an operand of type T, or
(11.9)
—
a function with a return type or argument type of type T is defined (6.1) or called (8.5.1.2), or
(11.10)
—
a class with a base class of type T is defined (Clause 13), or
(11.11)
—
an lvalue of type T is assigned to (8.5.18), or
(11.12)
—
the type T is the subject of an alignof expression (8.5.2.6), or
(11.13)
—
an exception-declaration has type T, reference to T, or pointer to T (18.3).
— end note ]
12
There can be more than one definition of a class type (Clause 12), enumeration type (10.2), inline function
with external linkage (10.1.6), inline variable with external linkage (10.1.6), class template (Clause 17),
non-static function template (17.6.6), concept (17.6.8), static data member of a class template (17.6.1.3),
member function of a class template (17.6.1.1), or template specialization for which some template parameters
are not specified (17.8, 17.6.5) in a program provided that each definition appears in a different translation
unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined
in more than one translation unit, then
(12.1)
—
each definition of D shall consist of the same sequence of tokens; and
(12.2)
—
in each definition of D, corresponding names, looked up according to 6.4, shall refer to an entity defined
within the definition of D, or shall refer to the same entity, after overload resolution (16.3) and after
matching of partial template specialization (17.9.3), except that a name can refer to
(12.2.1)
—
a non-volatile const object with internal or no linkage if the object
(12.2.1.1)
—
has the same literal type in all definitions of D,
(12.2.1.2)
—
is initialized with a constant expression (8.6),
(12.2.1.3)
—
is not odr-used in any definition of D, and
(12.2.1.4)
—
has the same value in all definitions of D,
or
(12.2.2)
—
a reference with internal or no linkage initialized with a constant expression such that the reference
refers to the same entity in all definitions of D;
and
(12.3)
—
in each definition of D, corresponding entities shall have the same language linkage; and
(12.4)
—
in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions,
constructors, operator new functions and operator delete functions, shall refer to the same function, or
to a function defined within the definition of D; and
(12.5)
—
in each definition of D, a default argument used by an (implicit or explicit) function call is treated as if
its token sequence were present in the definition of D; that is, the default argument is subject to the
requirements described in this paragraph (and, if the default argument has subexpressions with default
arguments, this requirement applies recursively)23; and
23) 11.3.6 describes how default argument names are looked up.
§ 6.2
28
(12.6)
—
if D is a class with an implicitly-declared constructor (15.1), it is as if the constructor was implicitly
defined in every translation unit where it is odr-used, and the implicit definition in every translation
unit shall call the same constructor for a subobject of D. [ Example:
// translation unit 1:
struct X {
X(int, int);
X(int, int, int);
};
X::X(int, int = 0) { }
class D {
X x = 0;
};
D d1;
// X(int, int) called by D()
// translation unit 2:
struct X {
X(int, int);
X(int, int, int);
};
X::X(int, int = 0, int = 0) { }
class D {
X x = 0;
};
D d2;
// X(int, int, int) called by D();
// D()’s implicit definition violates the ODR
— end example ]
If D is a template and is defined in more than one translation unit, then the preceding requirements shall
apply both to names from the template’s enclosing scope used in the template definition (17.7.3), and also to
dependent names at the point of instantiation (17.7.2). If the definitions of D satisfy all these requirements,
then the behavior is as if there were a single definition of D. [Note: The entity is still declared in multiple
translation units, and 6.5 still applies to these declarations. In particular, lambda-expressions (8.4.5) appearing
in the type of D may result in the different declarations having distinct types.
— end note ] If the definitions
of D do not satisfy these requirements, then the behavior is undefined.
6.3
Scope
[basic.scope]
6.3.1
Declarative regions and scopes
[basic.scope.declarative]
1
Every name is introduced in some portion of program text called a declarative region, which is the largest part
of the program in which that name is valid, that is, in which that name may be used as an unqualified name
to refer to the same entity. In general, each particular name is valid only within some possibly discontiguous
portion of program text called its scope. To determine the scope of a declaration, it is sometimes convenient
to refer to the potential scope of a declaration. The scope of a declaration is the same as its potential scope
unless the potential scope contains another declaration of the same name. In that case, the potential scope of
the declaration in the inner (contained) declarative region is excluded from the scope of the declaration in
the outer (containing) declarative region.
2
[ Example: In
int j = 24;
int main() {
int i = j, j;
j = 42;
}
the identifier j is declared twice as a name (and used twice). The declarative region of the first j includes
the entire example. The potential scope of the first j begins immediately after that j and extends to the end
of the program, but its (actual) scope excludes the text between the , and the }. The declarative region of
the second declaration of j (the j immediately before the semicolon) includes all the text between { and },
but its potential scope excludes the declaration of i. The scope of the second declaration of j is the same as
its potential scope.
— end example ]
§ 6.3.1
29
3
The names declared by a declaration are introduced into the scope in which the declaration occurs, except
that the presence of a friend specifier (14.3), certain uses of the elaborated-type-specifier (10.1.7.3), and
using-directives (10.3.4) alter this general behavior.
4
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
(4.1)
—
they shall all refer to the same entity, or all refer to functions and function templates; or
(4.2)
—
exactly one declaration shall declare a class name or enumeration name that is not a typedef name
and the other declarations shall all refer to the same variable, non-static data member, or enumerator,
or all refer to functions and function templates; in this case the class name or enumeration name is
hidden (6.3.10). [ Note: A namespace name or a class template name must be unique in its declarative
region (10.3.2, Clause 17).
— end note ]
[Note: These restrictions apply to the declarative region into which a name is introduced, which is not
necessarily the same as the region in which the declaration occurs. In particular, elaborated-type-specifiers
(10.1.7.3) and friend declarations (14.3) may introduce a (possibly not visible) name into an enclosing
namespace; these restrictions apply to that region. Local extern declarations (6.5) may introduce a name
into the declarative region where the declaration appears and also introduce a (possibly not visible) name
into an enclosing namespace; these restrictions apply to both regions.
— end note ]
5
For a given declarative region R and a point P outside R, the set of intervening declarative regions between
P and R comprises all declarative regions that are or enclose R and do not enclose P.
6
[ Note: The name lookup rules are summarized in 6.4.
— end note ]
6.3.2
Point of declaration
[basic.scope.pdecl]
1
The point of declaration for a name is immediately after its complete declarator (Clause 11) and before its
initializer (if any), except as noted below. [ Example:
unsigned char x = 12;
{ unsigned char x = x; }
Here the second x is initialized with its own (indeterminate) value.
— end example ]
2
[ Note: A name from an outer scope remains visible up to the point of declaration of the name that hides it.
[ Example:
const int i = 2;
{ int i[i]; }
declares a block-scope array of two integers.
— end example ]
— end note ]
3
The point of declaration for a class or class template first declared by a class-specifier is immediately after
the identifier or simple-template-id (if any) in its class-head (Clause 12). The point of declaration for
an enumeration is immediately after the identifier (if any) in either its enum-specifier (10.2) or its first
opaque-enum-declaration (10.2), whichever comes first. The point of declaration of an alias or alias template
immediately follows the type-id to which the alias refers.
4
The point of declaration of a using-declarator that does not name a constructor is immediately after the
using-declarator (10.3.3).
5
The point of declaration for an enumerator is immediately after its enumerator-definition. [ Example:
const int x = 12;
{ enum { x = x }; }
Here, the enumerator x is initialized with the value of the constant x, namely 12.
— end example ]
6
After the point of declaration of a class member, the member name can be looked up in the scope of its class.
[ Note: This is true even if the class is an incomplete class. For example,
struct X {
enum E { z = 16 };
int b[X::z];
// OK
};
— end note ]
7
The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
(7.1)
—
for a declaration of the form
§ 6.3.2
30
class-key attribute-specifier-seqopt identifier ;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
(7.2)
—
for an elaborated-type-specifier of the form
class-key identifier
if the elaborated-type-specifier is used in the decl-specifier-seq or parameter-declaration-clause of a
function defined in namespace scope, the identifier is declared as a class-name in the namespace that
contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the
smallest namespace or block scope that contains the declaration. [ Note: These rules also apply within
templates.
— end note ] [Note: Other forms of elaborated-type-specifier do not declare a new name,
and therefore must refer to an existing type-name. See 6.4.4 and 10.1.7.3.
— end note ]
8
The point of declaration for an injected-class-name (Clause 12) is immediately following the opening brace of
the class definition.
9
The point of declaration for a function-local predefined variable (11.4) is immediately before the function-body
of a function definition.
10
The point of declaration for the variable or the structured bindings declared in the for-range-declaration of a
range-based for statement (9.5.4) is immediately after the for-range-initializer.
11
The point of declaration for a template parameter is immediately after its complete template-parameter.
[ Example:
typedef unsigned char T;
template<class T
= T
// lookup finds the typedef name of unsigned char
, T
// lookup finds the template parameter
N = 0> struct A { };
— end example ]
12
[ Note: Friend declarations refer to functions or classes that are members of the nearest enclosing namespace,
but they do not introduce new names into that namespace (10.3.1.2). Function declarations at block scope
and variable declarations with the extern specifier at block scope refer to declarations that are members of
an enclosing namespace, but they do not introduce new names into that scope.
— end note ]
13
[ Note: For point of instantiation of a template, see 17.7.4.1. — end note ]
6.3.3
Block scope
[basic.scope.block]
1
A name declared in a block (9.3) is local to that block; it has block scope. Its potential scope begins at its
point of declaration (6.3.2) and ends at the end of its block. A variable declared at block scope is a local
variable.
2
The name declared in an exception-declaration is local to the handler and shall not be redeclared in the
outermost block of the handler.
3
Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and
switch statements are local to the if, while, for, or switch statement (including the controlled statement),
and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for
the if statement, any of the outermost blocks) of the controlled statement; see 9.4.
6.3.4
Function parameter scope
[basic.scope.param]
1
A function parameter (including one appearing in a lambda-declarator ) or function-local predefined variable
(11.4) has function parameter scope. The potential scope of a parameter or function-local predefined variable
begins at its point of declaration. If the nearest enclosing function declarator is not the declarator of a
function definition, the potential scope ends at the end of that function declarator. Otherwise, if the function
has a function-try-block the potential scope ends at the end of the last associated handler. Otherwise the
potential scope ends at the end of the outermost block of the function definition. A parameter name shall
not be redeclared in the outermost block of the function definition nor in the outermost block of any handler
associated with a function-try-block.
6.3.5
Function scope
[basic.funscope]
1
Labels (9.1) have function scope and may be used anywhere in the function in which they are declared. Only
labels have function scope.
§ 6.3.5
31
6.3.6
Namespace scope
[basic.scope.namespace]
1
The declarative region of a namespace-definition is its namespace-body. Entities declared in a namespace-body
are said to be members of the namespace, and names introduced by these declarations into the declarative
region of the namespace are said to be member names of the namespace. A namespace member name has
namespace scope. Its potential scope includes its namespace from the name’s point of declaration (6.3.2)
onwards; and for each using-directive (10.3.4) that nominates the member’s namespace, the member’s potential
scope includes that portion of the potential scope of the using-directive that follows the member’s point of
declaration. [ Example:
namespace N {
int i;
int g(int a) { return a; }
int j();
void q();
}
namespace { int l=1; }
// the potential scope of l is from its point of declaration to the end of the translation unit
namespace N {
int g(char a) {
// overloads N::g(int)
return l+a;
// l is from unnamed namespace
}
int i;
// error: duplicate definition
int j();
// OK: duplicate function declaration
int j() {
// OK: definition of N::j()
return g(i);
// calls N::g(int)
}
int q();
// error: different return type
}
— end example ]
2
A namespace member can also be referred to after the :: scope resolution operator (8.4) applied to the name
of its namespace or the name of a namespace which nominates the member’s namespace in a using-directive;
see 6.4.3.2.
3
The outermost declarative region of a translation unit is also a namespace, called the global namespace. A
name declared in the global namespace has global namespace scope (also called global scope). The potential
scope of such a name begins at its point of declaration (6.3.2) and ends at the end of the translation unit
that is its declarative region. A name with global namespace scope is said to be a global name.
6.3.7
Class scope
[basic.scope.class]
1
The potential scope of a name declared in a class consists not only of the declarative region following the
name’s point of declaration, but also of all function bodies, default arguments, noexcept-specifiers, and
brace-or-equal-initializer s of non-static data members in that class (including such things in nested classes).
2
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the
completed scope of S. No diagnostic is required for a violation of this rule.
3
A name declared within a member function hides a declaration of the same name whose scope extends to or
past the end of the member function’s class.
4
The potential scope of a declaration that extends to or past the end of a class definition also extends to the
regions defined by its member definitions, even if the members are defined lexically outside the class (this
includes static data member definitions, nested class definitions, and member function definitions, including
the member function body and any portion of the declarator part of such definitions which follows the
declarator-id, including a parameter-declaration-clause and any default arguments (11.3.6)).
5
[ Example:
typedef int c;
enum { i = 1 };
§ 6.3.7
32
class X {
char v[i];
// error: i refers to ::i but when reevaluated is X::i
int f() { return sizeof(c); }
// OK: X::c
char c;
enum { i = 2 };
};
typedef char* T;
struct Y {
T a;
// error: T refers to ::T but when reevaluated is Y::T
typedef long T;
T b;
};
typedef int I;
class D {
typedef I I;
// error, even though no reordering involved
};
— end example ]
6
The name of a class member shall only be used as follows:
(6.1)
—
in the scope of its class (as described above) or a class derived (Clause 13) from its class,
(6.2)
—
after the . operator applied to an expression of the type of its class (8.5.1.5) or a class derived from its
class,
(6.3)
—
after the -> operator applied to a pointer to an object of its class (8.5.1.5) or a class derived from its
class,
(6.4)
—
after the :: scope resolution operator (8.4) applied to the name of its class or a class derived from its
class.
6.3.8
Enumeration scope
[basic.scope.enum]
1
The name of a scoped enumerator (10.2) has enumeration scope. Its potential scope begins at its point of
declaration and terminates at the end of the enum-specifier.
6.3.9
Template parameter scope
[basic.scope.temp]
1
The declarative region of the name of a template parameter of a template template-parameter is the smallest
template-parameter-list in which the name was introduced.
2
The declarative region of the name of a template parameter of a template is the smallest template-declaration
in which the name was introduced. Only template parameter names belong to this declarative region; any
other kind of name introduced by the declaration of a template-declaration is instead introduced into the
same declarative region where it would be introduced as a result of a non-template declaration of the same
name. [ Example:
namespace N {
template<class T> struct A { };
// #1
template<class U> void f(U) { }
// #2
struct B {
template<class V> friend int g(struct C*);
// #3
};
}
The declarative regions of T, U and V are the template-declarations on lines #1, #2, and #3, respectively.
But the names A, f, g and C all belong to the same declarative region — namely, the namespace-body of N.
(g is still considered to belong to this declarative region in spite of its being hidden during qualified and
unqualified name lookup.)
— end example ]
3
The potential scope of a template parameter name begins at its point of declaration (6.3.2) and ends
at the end of its declarative region.
[Note: This implies that a template-parameter can be used in the
declaration of subsequent template-parameter s and their default arguments but cannot be used in preceding
template-parameter s or their default arguments. For example,
template<class T, T* p, class U = T> class X { /* ... */ };
template<class T> void f(T* p = new T);
§ 6.3.9
33
This also implies that a template-parameter can be used in the specification of base classes. For example,
template<class T> class X : public Array<T> { /* ... */ };
template<class T> class Y : public T { /* ... */ };
The use of a template parameter as a base class implies that a class used as a template argument must be
defined and not just declared when the class template is instantiated.
— end note ]
4
The declarative region of the name of a template parameter is nested within the immediately-enclosing
declarative region.
[Note: As a result, a template-parameter hides any entity with the same name in an
enclosing scope (6.3.10). [ Example:
typedef int N;
template<N X, typename N, template<N Y> class T> struct A;
Here, X is a non-type template parameter of type int and Y is a non-type template parameter of the same
type as the second template parameter of A. — end example ] — end note ]
5
[ Note: Because the name of a template parameter cannot be redeclared within its potential scope (17.7.1), a
template parameter’s scope is often its potential scope. However, it is still possible for a template parameter
name to be hidden; see 17.7.1.
— end note ]
6.3.10
Name hiding
[basic.scope.hiding]
1
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived
class (13.2).
2
A class name (12.1) or enumeration name (10.2) can be hidden by the name of a variable, data member,
function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data
member, function, or enumerator are declared in the same scope (in any order) with the same name, the class
or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
3
In a member function definition, the declaration of a name at block scope hides the declaration of a member
of the class with the same name; see 6.3.7. The declaration of a member in a derived class (Clause 13) hides
the declaration of a member of a base class of the same name; see 13.2.
4
During the lookup of a name qualified by a namespace name, declarations that would otherwise be made
visible by a using-directive can be hidden by declarations with the same name in the namespace containing
the using-directive; see 6.4.3.2.
5
If a name is in scope and is not hidden it is said to be visible.
6.4
Name lookup
[basic.lookup]
1
The name lookup rules apply uniformly to all names (including typedef-names (10.1.3), namespace-names
(10.3), and class-names (12.1)) wherever the grammar allows such names in the context discussed by a
particular rule. Name lookup associates the use of a name with a set of declarations (6.1) of that name. The
declarations found by name lookup shall either all declare the same entity or shall all declare functions; in the
latter case, the declarations are said to form a set of overloaded functions (16.1). Overload resolution (16.3)
takes place after name lookup has succeeded. The access rules (Clause 14) are considered only once name
lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the
name’s declaration used further in expression processing (Clause 8).
2
A name “looked up in the context of an expression” is looked up as an unqualified name in the scope where
the expression is found.
3
The injected-class-name of a class (Clause 12) is also considered to be a member of that class for the purposes
of name hiding and lookup.
4
[ Note: 6.5 discusses linkage issues. The notions of scope, point of declaration and name hiding are discussed
in 6.3.
— end note ]
6.4.1
Unqualified name lookup
[basic.lookup.unqual]
1
In all the cases listed in 6.4.1, the scopes are searched for a declaration in the order listed in each of the
respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is
found, the program is ill-formed.
2
The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing
the using-directive; see 10.3.4. For the purpose of the unqualified name lookup rules described in 6.4.1, the
§ 6.4.1
34
declarations from the namespace nominated by the using-directive are considered members of that enclosing
namespace.
3
The lookup for an unqualified name used as the postfix-expression of a function call is described in 6.4.2. [ Note:
For purposes of determining (during parsing) whether an expression is a postfix-expression for a function call,
the usual name lookup rules apply. In some cases a name followed by < is treated as a template-name even
though name lookup did not find a template-name (see 17.2). For example,
int h;
void g();
namespace N {
struct A {};
template <class T> int f(T);
template <class T> int g(T);
template <class T> int h(T);
}
int x = f<N::A>(N::A());
// OK: lookup of f finds nothing, f treated as template name
int y = g<N::A>(N::A());
// OK: lookup of g finds a function, g treated as template name
int z = h<N::A>(N::A());
// error: h< does not begin a template-id
The rules in 6.4.2 have no effect on the syntactic interpretation of an expression. For example,
typedef int f;
namespace N {
struct A {
friend void f(A &);
operator int();
void g(A a) {
int i = f(a);
// f is the typedef, not the friend function: equivalent to int(a)
}
};
}
Because the expression is not a function call, the argument-dependent name lookup (6.4.2) does not apply
and the friend function f is not found.
— end note ]
4
A name used in global scope, outside of any function, class or user-declared namespace, shall be declared
before its use in global scope.
5
A name used in a user-declared namespace outside of the definition of any function or class shall be declared
before its use in that namespace or before its use in a namespace enclosing its namespace.
6
In the definition of a function that is a member of namespace N, a name used after the function’s declarator-id24
shall be declared before its use in the block in which it is used or in one of its enclosing blocks (9.3) or shall
be declared before its use in namespace N or, if N is a nested namespace, shall be declared before its use in
one of N’s enclosing namespaces. [ Example:
namespace A {
namespace N {
void f();
}
}
void A::N::f() {
i = 5;
// The following scopes are searched for a declaration of i:
// 1) outermost block scope of A::N::f, before the use of i
// 2) scope of namespace N
// 3) scope of namespace A
// 4) global scope, before the definition of A::N::f
}
— end example ]
24) This refers to unqualified names that occur, for instance, in a type or default argument in the parameter-declaration-clause
or used in the function body.
§ 6.4.1
35
7
A name used in the definition of a class X outside of a member function body, default argument, noexcept-
specifier, brace-or-equal-initializer of a non-static data member, or nested class definition25 shall be declared
in one of the following ways:
(7.1)
—
before its use in class X or be a member of a base class of X (13.2), or
(7.2)
—
if X is a nested class of class Y (12.2.5), before the definition of X in Y, or shall be a member of a base
class of Y (this lookup applies in turn to Y’s enclosing classes, starting with the innermost enclosing
class),26 or
(7.3)
—
if X is a local class (12.4) or is a nested class of a local class, before the definition of class X in a block
enclosing the definition of class X, or
(7.4)
—
if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class
or a nested class within a local class of a function that is a member of N, before the definition of class X
in namespace N or in one of N’s enclosing namespaces.
[ Example:
namespace M {
class B { };
}
namespace N {
class Y : public M::B {
class X {
int a[i];
};
};
}
// The following scopes are searched for a declaration of i:
// 1) scope of class N::Y::X, before the use of i
// 2) scope of class N::Y, before the definition of N::Y::X
// 3) scope of N::Y’s base class M::B
// 4) scope of namespace N, before the definition of N::Y
// 5) global scope, before the definition of N
— end example ] [ Note: When looking for a prior declaration of a class or function introduced by a friend
declaration, scopes outside of the innermost enclosing namespace scope are not considered; see 10.3.1.2.
— end note ] [Note: 6.3.7 further describes the restrictions on the use of names in a class definition. 12.2.5
further describes the restrictions on the use of names in nested class definitions. 12.4 further describes the
restrictions on the use of names in local class definitions.
— end note ]
8
For the members of a class X, a name used in a member function body, in a default argument, in a noexcept-
specifier, in the brace-or-equal-initializer of a non-static data member (12.2), or in the definition of a class
member outside of the definition of X, following the member’s declarator-id27, shall be declared in one of the
following ways:
(8.1)
—
before its use in the block in which it is used or in an enclosing block (9.3), or
(8.2)
—
shall be a member of class X or be a member of a base class of X (13.2), or
(8.3)
—
if X is a nested class of class Y (12.2.5), shall be a member of Y, or shall be a member of a base class of
Y (this lookup applies in turn to Y’s enclosing classes, starting with the innermost enclosing class),28 or
(8.4)
—
if X is a local class (12.4) or is a nested class of a local class, before the definition of class X in a block
enclosing the definition of class X, or
(8.5)
—
if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class
or a nested class within a local class of a function that is a member of N, before the use of the name, in
namespace N or in one of N’s enclosing namespaces.
25) This refers to unqualified names following the class name; such a name may be used in the base-clause or may be used in
the class definition.
26) This lookup applies whether the definition of X is nested within Y’s definition or whether X’s definition appears in a
namespace scope enclosing Y’s definition (12.2.5).
27) That is, an unqualified name that occurs, for instance, in a type in the parameter-declaration-clause or in the noexcept-
specifier.
28) This lookup applies whether the member function is defined within the definition of class X or whether the member function
is defined in a namespace scope enclosing X’s definition.
§ 6.4.1
36
[ Example:
class B { };
namespace M {
namespace N {
class X : public B {
void f();
};
}
}
void M::N::X::f() {
i = 16;
}
// The following scopes are searched for a declaration of i:
// 1) outermost block scope of M::N::X::f, before the use of i
// 2) scope of class M::N::X
// 3) scope of M::N::X’s base class B
// 4) scope of namespace M::N
// 5) scope of namespace M
// 6) global scope, before the definition of M::N::X::f
— end example ] [Note: 12.2.1 and 12.2.3 further describe the restrictions on the use of names in member
function definitions.
12.2.5 further describes the restrictions on the use of names in the scope of nested
classes. 12.4 further describes the restrictions on the use of names in local class definitions.
— end note ]
9
Name lookup for a name used in the definition of a friend function (14.3) defined inline in the class granting
friendship shall proceed as described for lookup in member function definitions. If the friend function is
not defined in the class granting friendship, name lookup in the friend function definition shall proceed as
described for lookup in namespace member function definitions.
10
In a friend declaration naming a member function, a name used in the function declarator and not part of a
template-argument in the declarator-id is first looked up in the scope of the member function’s class (13.2). If
it is not found, or if the name is part of a template-argument in the declarator-id, the look up is as described
for unqualified names in the definition of the class granting friendship. [ Example:
struct A {
typedef int AT;
void f1(AT);
void f2(float);
template <class T> void f3();
};
struct B {
typedef char AT;
typedef float BT;
friend void A::f1(AT);
// parameter type is A::AT
friend void A::f2(BT);
// parameter type is B::BT
friend void A::f3<AT>();
// template argument is B::AT
};
— end example ]
11
During the lookup for a name used as a default argument (11.3.6) in a function parameter-declaration-clause
or used in the expression of a mem-initializer for a constructor (15.6.2), the function parameter names are
visible and hide the names of entities declared in the block, class or namespace scopes containing the function
declaration. [ Note: 11.3.6 further describes the restrictions on the use of names in default arguments. 15.6.2
further describes the restrictions on the use of names in a ctor-initializer.
— end note ]
12
During the lookup of a name used in the constant-expression of an enumerator-definition, previously declared
enumerators of the enumeration are visible and hide the names of entities declared in the block, class, or
namespace scopes containing the enum-specifier.
13
A name used in the definition of a static data member of class X (12.2.3.2) (after the qualified-id of the
static member) is looked up as if the name was used in a member function of X. [Note: 12.2.3.2 further
describes the restrictions on the use of names in the definition of a static data member.
— end note ]
§ 6.4.1
37
14
If a variable member of a namespace is defined outside of the scope of its namespace then any name that
appears in the definition of the member (after the declarator-id) is looked up as if the definition of the
member occurred in its namespace. [ Example:
namespace N {
int i = 4;
extern int j;
}
int i = 2;
int N::j = i;
// N::j == 4
— end example ]
15
A name used in the handler for a function-try-block (Clause 18) is looked up as if the name was used in
the outermost block of the function definition. In particular, the function parameter names shall not be
redeclared in the exception-declaration nor in the outermost block of a handler for the function-try-block.
Names declared in the outermost block of the function definition are not found when looked up in the scope
of a handler for the function-try-block. [ Note: But function parameter names are found.
— end note ]
16
[ Note: The rules for name lookup in template definitions are described in 17.7.
— end note ]
6.4.2
Argument-dependent name lookup
[basic.lookup.argdep]
1
When the postfix-expression in a function call (8.5.1.2) is an unqualified-id, other namespaces not considered
during the usual unqualified lookup (6.4.1) may be searched, and in those namespaces, namespace-scope friend
function or function template declarations (14.3) not otherwise visible may be found. These modifications to
the search depend on the types of the arguments (and for template template arguments, the namespace of
the template argument). [ Example:
namespace N {
struct S { };
void f(S);
}
void g() {
N::S s;
f(s);
// OK: calls N::f
(f)(s);
// error: N::f not considered; parentheses prevent argument-dependent lookup
}
— end example ]
2
For each argument type T in the function call, there is a set of zero or more associated namespaces and a
set of zero or more associated classes to be considered. The sets of namespaces and classes are determined
entirely by the types of the function arguments (and the namespace of any template template argument).
Typedef names and using-declarations used to specify the types do not contribute to this set. The sets of
namespaces and classes are determined in the following way:
(2.1)
—
If T is a fundamental type, its associated sets of namespaces and classes are both empty.
—
(2.2)
If T is a class type (including unions), its associated classes are: the class itself; the class of which it is
a member, if any; and its direct and indirect base classes. Its associated namespaces are the innermost
enclosing namespaces of its associated classes. Furthermore, if T is a class template specialization,
its associated namespaces and classes also include: the namespaces and classes associated with the
types of the template arguments provided for template type parameters (excluding template template
parameters); the namespaces of which any template template arguments are members; and the classes
of which any member templates used as template template arguments are members. [ Note: Non-type
template arguments do not contribute to the set of associated namespaces. — end note ]
(2.3)
—
If T is an enumeration type, its associated namespace is the innermost enclosing namespace of its
declaration. If it is a class member, its associated class is the member’s class; else it has no associated
class.
(2.4)
—
If T is a pointer to U or an array of U, its associated namespaces and classes are those associated with U.
(2.5)
—
If T is a function type, its associated namespaces and classes are those associated with the function
parameter types and those associated with the return type.
§ 6.4.2
38
(2.6)
—
If T is a pointer to a member function of a class X, its associated namespaces and classes are those
associated with the function parameter types and return type, together with those associated with X.
(2.7)
—
If T is a pointer to a data member of class X, its associated namespaces and classes are those associated
with the member type together with those associated with X.
If an associated namespace is an inline namespace (10.3.1), its enclosing namespace is also included in the set.
If an associated namespace directly contains inline namespaces, those inline namespaces are also included in
the set. In addition, if the argument is the name or address of a set of overloaded functions and/or function
templates, its associated classes and namespaces are the union of those associated with each of the members
of the set, i.e., the classes and namespaces associated with its parameter types and return type. Additionally,
if the aforementioned set of overloaded functions is named with a template-id, its associated classes and
namespaces also include those of its type template-arguments and its template template-arguments.
3
Let X be the lookup set produced by unqualified lookup (6.4.1) and let Y be the lookup set produced by
argument dependent lookup (defined as follows). If X contains
(3.1)
—
a declaration of a class member, or
(3.2)
—
a block-scope function declaration that is not a using-declaration, or
(3.3)
—
a declaration that is neither a function nor a function template
then Y is empty. Otherwise Y is the set of declarations found in the namespaces associated with the argument
types as described below. The set of declarations found by the lookup of the name is the union of X and Y.
[ Note: The namespaces and classes associated with the argument types can include namespaces and classes
already considered by the ordinary unqualified lookup.
— end note ] [ Example:
namespace NS {
class T { };
void f(T);
void g(T, int);
}
NS::T parm;
void g(NS::T, float);
int main() {
f(parm);
// OK: calls NS::f
extern void g(NS::T, float);
g(parm, 1);
// OK: calls g(NS::T, float)
}
— end example ]
4
When considering an associated namespace, the lookup is the same as the lookup performed when the
associated namespace is used as a qualifier (6.4.3.2) except that:
(4.1)
—
Any using-directives in the associated namespace are ignored.
(4.2)
—
Any namespace-scope friend functions or friend function templates (14.3) declared in associated
classes are visible within their respective namespaces even if they are not visible during an ordinary
lookup (10.3.1.2).
(4.3)
—
All names except those of (possibly overloaded) functions and function templates are ignored.
6.4.3
Qualified name lookup
[basic.lookup.qual]
1
The name of a class or namespace member or enumerator can be referred to after the :: scope resolution
operator (8.4) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a ::
scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the
name preceding that :: considers only namespaces, types, and templates whose specializations are types. If
the name found does not designate a namespace or a class, enumeration, or dependent type, the program is
ill-formed. [ Example:
class A {
public:
static int n;
};
int main() {
int A;
A::n = 42;
// OK
§ 6.4.3
39
A b;
// ill-formed: A does not name a type
}
— end example ]
2
[Note: Multiply qualified names, such as N1::N2::N3::n, can be used to refer to members of nested
classes (12.2.5) or members of nested namespaces.
— end note ]
3
In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared
are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of
the member’s class or namespace. [ Example:
class X { };
class C {
class X { };
static const int number = 50;
static X arr[number];
};
X C::arr[number];
// ill-formed:
// equivalent to ::X C::arr[C::number];
// and not to C::X C::arr[C::number];
— end example ]
4
A name prefixed by the unary scope operator :: (8.4) is looked up in global scope, in the translation unit
where it is used. The name shall be declared in global namespace scope or shall be a name whose declaration
is visible in global scope because of a using-directive (6.4.3.2). The use of :: allows a global name to be
referred to even if its identifier has been hidden (6.3.10).
5
A name prefixed by a nested-name-specifier that nominates an enumeration type shall represent an enumerator
of that enumeration.
6
If a pseudo-destructor-name (8.5.1.4) contains a nested-name-specifier, the type-names are looked up as types
in the scope designated by the nested-name-specifier. Similarly, in a qualified-id of the form:
nested-name-specifieropt class-name :: ~ class-name
the second class-name is looked up in the same scope as the first. [ Example:
struct C {
typedef int I;
};
typedef int I1, I2;
extern int* p;
extern int* q;
p->C::I::~I();
// I is looked up in the scope of C
q->I1::~I2();
// I2 is looked up in the scope of the postfix-expression
struct A {
~A();
};
typedef A AB;
int main() {
AB* p;
p->AB::~AB();
// explicitly calls the destructor for A
}
— end example ] [ Note: 6.4.5 describes how name lookup proceeds after the . and -> operators. — end note ]
6.4.3.1
Class members
[class.qual]
1
If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-
specifier is looked up in the scope of the class (13.2), except for the cases listed below. The name shall
represent one or more members of that class or of one of its base classes (Clause 13). [ Note: A class member
can be referred to using a qualified-id at any point in its potential scope (6.3.7).
— end note ] The exceptions
to the name lookup rule above are the following:
(1.1)
—
the lookup for a destructor is as specified in 6.4.3;
(1.2)
—
a conversion-type-id of a conversion-function-id is looked up in the same manner as a conversion-type-id
in a class member access (see 6.4.5);
§ 6.4.3.1
40
(1.3)
—
the names in a template-argument of a template-id are looked up in the context in which the entire
postfix-expression occurs.
(1.4)
—
the lookup for a name specified in a using-declaration (10.3.3) also finds class or enumeration names
hidden within the same scope (6.3.10).
2
In a lookup in which function names are not ignored29 and the nested-name-specifier nominates a class C:
(2.1)
—
if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of
C (Clause 12), or
(2.2)
—
in a using-declarator of a using-declaration (10.3.3) that is a member-declaration, if the name specified
after the nested-name-specifier is the same as the identifier or the simple-template-id’s template-name
in the last component of the nested-name-specifier,
the name is instead considered to name the constructor of class C. [ Note: For example, the constructor is not
an acceptable lookup result in an elaborated-type-specifier so the constructor would not be used in place of
the injected-class-name.
— end note ] Such a constructor name shall be used only in the declarator-id of a
declaration that names a constructor or in a using-declaration. [ Example:
struct A { A(); };
struct B: public A { B(); };
A::A() { }
B::B() { }
B::A ba;
// object of type A
A::A a;
// error, A::A is not a type name
struct A::A a2;
// object of type A
— end example ]
3
A class member name hidden by a name in a nested declarative region or by the name of a derived class
member can still be found if qualified by the name of its class followed by the :: operator.
6.4.3.2
Namespace members
[namespace.qual]
1
If the nested-name-specifier of a qualified-id nominates a namespace (including the case where the nested-
name-specifier is ::, i.e., nominating the global namespace), the name specified after the nested-name-specifier
is looked up in the scope of the namespace. The names in a template-argument of a template-id are looked
up in the context in which the entire postfix-expression occurs.
2
For a namespace X and name m, the namespace-qualified lookup set S(X, m) is defined as follows: Let
S′(X,m) be the set of all declarations of m in X and the inline namespace set of X (10.3.1). If S′(X,m) is not
empty, S(X,m) is S′(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all namespaces Ni nominated
by using-directives in X and its inline namespace set.
3
Given X::m (where X is a user-declared namespace), or given ::m (where X is the global namespace), if
S(X,m) is the empty set, the program is ill-formed. Otherwise, if S(X,m) has exactly one member, or if
the context of the reference is a using-declaration (10.3.3), S(X,m) is the required set of declarations of m.
Otherwise if the use of m is not one that allows a unique declaration to be chosen from S(X, m), the program
is ill-formed. [ Example:
int x;
namespace Y {
void f(float);
void h(int);
}
namespace Z {
void h(double);
}
namespace A {
using namespace Y;
void f(int);
29) Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier,
or a base-specifier.
§ 6.4.3.2
41
void g(int);
int i;
}
namespace B {
using namespace
Z;
void f(char);
int i;
}
namespace AB {
using namespace
A;
using namespace
B;
void g();
}
void h()
{
AB::g();
// g is declared directly in AB, therefore S is {AB::g()} and AB::g() is chosen
AB::f(1);
// f is not declared directly in AB so the rules are applied recursively to A and B;
// namespace Y is not searched and Y::f(float) is not considered;
// S is {A::f(int), B::f(char)} and overload resolution chooses A::f(int)
AB::f(’c’);
// as above but resolution chooses B::f(char)
AB::x++;
// x is not declared directly in AB, and is not declared in A or B, so the rules
// are applied recursively to Y and Z, S is {} so the program is ill-formed
AB::i++;
// i is not declared directly in AB so the rules are applied recursively to A and B,
// S is {A::i, B::i} so the use is ambiguous and the program is ill-formed
AB::h(16.8);
// h is not declared directly in AB and not declared directly in A or B so the rules
// are applied recursively to Y and Z, S is {Y::h(int), Z::h(double)} and
// overload resolution chooses Z::h(double)
}
— end example ]
4
[ Note: The same declaration found more than once is not an ambiguity (because it is still a unique declaration).
[ Example:
namespace A {
int a;
}
namespace B {
using namespace A;
}
namespace C {
using namespace A;
}
namespace BC {
using namespace B;
using namespace C;
}
void f()
{
BC::a++;
// OK: S is {A::a, A::a}
}
§ 6.4.3.2
42
namespace D {
using A::a;
}
namespace BD {
using namespace B;
using namespace D;
}
void g()
{
BD::a++;
// OK: S is {A::a, A::a}
}
— end example ]
— end note ]
5
[ Example: Because each referenced namespace is searched at most once, the following is well-defined:
namespace B {
int b;
}
namespace A {
using namespace B;
int a;
}
namespace B {
using namespace A;
}
void f()
{
A::a++;
// OK: a declared directly in A, S is {A::a}
B::a++;
// OK: both A and B searched (once), S is {A::a}
A::b++;
// OK: both A and B searched (once), S is {B::b}
B::b++;
// OK: b declared directly in B, S is {B::b}
}
— end example ]
6
During the lookup of a qualified namespace member name, if the lookup finds more than one declaration of
the member, and if one declaration introduces a class name or enumeration name and the other declarations
either introduce the same variable, the same enumerator or a set of functions, the non-type name hides
the class or enumeration name if and only if the declarations are from the same namespace; otherwise (the
declarations are from different namespaces), the program is ill-formed. [ Example:
namespace A {
struct x { };
int x;
int y;
}
namespace B {
struct y { };
}
namespace C {
using namespace A;
using namespace B;
int i = C::x;
// OK, A::x (of type int)
int j = C::y;
// ambiguous, A::y or B::y
}
— end example ]
7
In a declaration for a namespace member in which the declarator-id is a qualified-id, given that the qualified-id
for the namespace member has the form
§ 6.4.3.2
43
nested-name-specifier unqualified-id
the unqualified-id shall name a member of the namespace designated by the nested-name-specifier or of an
element of the inline namespace set (10.3.1) of that namespace. [ Example:
namespace A {
namespace B {
void f1(int);
}
using namespace B;
}
void A::f1(int){ }
// ill-formed, f1 is not a member of A
— end example ] However, in such namespace member declarations, the nested-name-specifier may rely on
using-directives to implicitly provide the initial part of the nested-name-specifier. [ Example:
namespace A {
namespace B {
void f1(int);
}
}
namespace C {
namespace D {
void f1(int);
}
}
using namespace A;
using namespace C::D;
void B::f1(int){ }
// OK, defines A::B::f1(int)
— end example ]
6.4.4
Elaborated type specifiers
[basic.lookup.elab]
1
An elaborated-type-specifier (10.1.7.3) may be used to refer to a previously declared class-name or enum-name
even though the name has been hidden by a non-type declaration (6.3.10).
2
If the elaborated-type-specifier has no nested-name-specifier, and unless the elaborated-type-specifier appears
in a declaration with the following form:
class-key attribute-specifier-seqopt identifier ;
the identifier is looked up according to 6.4.1 but ignoring any non-type names that have been declared. If
the elaborated-type-specifier is introduced by the enum keyword and this lookup does not find a previously
declared type-name, the elaborated-type-specifier is ill-formed. If the elaborated-type-specifier is introduced by
the class-key and this lookup does not find a previously declared type-name, or if the elaborated-type-specifier
appears in a declaration with the form:
class-key attribute-specifier-seqopt identifier ;
the elaborated-type-specifier is a declaration that introduces the class-name as described in 6.3.2.
3
If the elaborated-type-specifier has a nested-name-specifier, qualified name lookup is performed, as described
in 6.4.3, but ignoring any non-type names that have been declared. If the name lookup does not find a
previously declared type-name, the elaborated-type-specifier is ill-formed. [ Example:
struct Node {
struct Node* Next;
// OK: Refers to Node at global scope
struct Data* Data;
// OK: Declares type Data at global scope and member Data
};
struct Data {
struct Node* Node;
// OK: Refers to Node at global scope
friend struct ::Glob;
// error: Glob is not declared, cannot introduce a qualified type (10.1.7.3)
friend struct Glob;
// OK: Refers to (as yet) undeclared Glob at global scope.
/* ... */
};
§ 6.4.4
44
struct Base {
struct Data;
// OK: Declares nested Data
struct ::Data*
thatData;
// OK: Refers to ::Data
struct Base::Data* thisData;
// OK: Refers to nested Data
friend class ::Data;
// OK: global Data is a friend
friend class Data;
// OK: nested Data is a friend
struct Data { /* ... */ };
// Defines nested Data
};
struct Data;
// OK: Redeclares Data at global scope
struct ::Data;
// error: cannot introduce a qualified type (10.1.7.3)
struct Base::Data;
// error: cannot introduce a qualified type (10.1.7.3)
struct Base::Datum;
// error: Datum undefined
struct Base::Data* pBase;
// OK: refers to nested Data
— end example ]
6.4.5
Class member access
[basic.lookup.classref]
1
In a class member access expression (8.5.1.5), if the . or -> token is immediately followed by an identifier
followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template
argument list (17.2) or a less-than operator. The identifier is first looked up in the class of the object
expression. If the identifier is not found, it is then looked up in the context of the entire postfix-expression
and shall name a class template.
2
If the id-expression in a class member access (8.5.1.5) is an unqualified-id, and the type of the object expression
is of a class type C, the unqualified-id is looked up in the scope of class C. For a pseudo-destructor call (8.5.1.4),
the unqualified-id is looked up in the context of the complete postfix-expression.
3
If the unqualified-id is ~type-name, the type-name is looked up in the context of the entire postfix-expression.
If the type T of the object expression is of a class type C, the type-name is also looked up in the scope of class
C. At least one of the lookups shall find a name that refers to cv T. [ Example:
struct A { };
struct B {
struct A { };
void f(::A* a);
};
void B::f(::A* a) {
a->~A();
// OK: lookup in *a finds the injected-class-name
}
— end example ]
4
If the id-expression in a class member access is a qualified-id of the form
class-name-or-namespace-name::...
the class-name-or-namespace-name following the . or -> operator is first looked up in the class of the
object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire
postfix-expression. [ Note: See 6.4.3, which describes the lookup of a name before ::, which will only find a
type or namespace name. — end note ]
5
If the qualified-id has the form
::class-name-or-namespace-name::...
the class-name-or-namespace-name is looked up in global scope as a class-name or namespace-name.
6
If the nested-name-specifier contains a simple-template-id (17.2), the names in its template-arguments are
looked up in the context in which the entire postfix-expression occurs.
7
If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the
object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire
postfix-expression. In each of these lookups, only names that denote types or templates whose specializations
are types are considered. [ Example:
struct A { };
§ 6.4.5
45
namespace N {
struct A {
void g() { }
template <class T> operator T();
};
}
int main() {
N::A a;
a.operator A();
// calls N::A::operator N::A
}
— end example ]
6.4.6
Using-directives and namespace aliases
[basic.lookup.udir]
1
In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in
a nested-name-specifier only namespace names are considered.
6.5
Program and linkage
[basic.link]
1
A program consists of one or more translation units (Clause 5) linked together. A translation unit consists of
a sequence of declarations.
translation-unit:
declaration-seqopt
2
A name is said to have linkage when it might denote the same object, reference, function, type, template,
namespace or value as a name introduced by a declaration in another scope:
(2.1)
—
When a name has external linkage, the entity it denotes can be referred to by names from scopes of
other translation units or from other scopes of the same translation unit.
(2.2)
—
When a name has internal linkage, the entity it denotes can be referred to by names from other scopes
in the same translation unit.
(2.3)
—
When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
3
A name having namespace scope (6.3.6) has internal linkage if it is the name of
(3.1)
—
a variable, function or function template that is explicitly declared static; or,
(3.2)
—
a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor
previously declared to have external linkage; or
(3.3)
—
a data member of an anonymous union.
4
An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
(4.1)
—
a variable; or
(4.2)
—
a function; or
(4.3)
—
a named class (Clause 12), or an unnamed class defined in a typedef declaration in which the class has
the typedef name for linkage purposes (10.1.3); or
(4.4)
—
a named enumeration (10.2), or an unnamed enumeration defined in a typedef declaration in which the
enumeration has the typedef name for linkage purposes (10.1.3); or
(4.5)
—
a template.
5
In addition, a member function, static data member, a named class or enumeration of class scope, or an
unnamed class or enumeration defined in a class-scope typedef declaration such that the class or enumeration
has the typedef name for linkage purposes (10.1.3), has the same linkage, if any, as the name of the class of
which it is a member.
6
The name of a function declared in block scope and the name of a variable declared by a block scope extern
declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and
type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration
declares that same entity and receives the linkage of the previous declaration. If there is more than one such
matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity
§ 6.5
46
receives external linkage. If, within a translation unit, the same entity is declared with both internal and
external linkage, the program is ill-formed. [ Example:
static void f();
static int i = 0;
// #1
void g() {
extern void f();
// internal linkage
int i;
// #2: i has no linkage
{
extern void f();
// internal linkage
extern int i;
// #3: external linkage, ill-formed
}
}
Without the declaration at line #2, the declaration at line #3 would link with the declaration at line #1.
Because the declaration with internal linkage is hidden, however, #3 is given external linkage, making the
program ill-formed.
— end example ]
7
When a block scope declaration of an entity with linkage is not found to refer to some other declaration,
then that entity is a member of the innermost enclosing namespace. However such a declaration does not
introduce the member name in its namespace scope. [ Example:
namespace X {
void p() {
q();
// error: q not yet declared
extern void q();
// q is a member of namespace X
}
void middle() {
q();
// error: q not yet declared
}
void q() { /* ... */ }
// definition of X::q
}
void q() { /* ... */ }
// some other, unrelated q
— end example ]
8
Names not covered by these rules have no linkage. Moreover, except as noted, a name declared at block
scope (6.3.3) has no linkage.
9
A type is said to have linkage if and only if:
(9.1)
—
it is a class or enumeration type that is named (or has a name for linkage purposes (10.1.3)) and the
name has linkage; or
(9.2)
—
it is an unnamed class or unnamed enumeration that is a member of a class with linkage; or
(9.3)
—
it is a specialization of a class template (Clause 17)30; or
(9.4)
—
it is a fundamental type (6.7.1); or
(9.5)
—
it is a compound type (6.7.2) other than a class or enumeration, compounded exclusively from types
that have linkage; or
(9.6)
—
it is a cv-qualified (6.7.3) version of a type that has linkage.
A type without linkage shall not be used as the type of a variable or function with external linkage unless
(9.7)
—
the entity has C language linkage (10.5), or
(9.8)
—
the entity is not odr-used (6.2) or is defined in the same translation unit.
[ Note: In other words, a type without linkage contains a class or enumeration that cannot be named outside
its translation unit. An entity with external linkage declared using such a type could not correspond to any
other entity in another translation unit of the program and thus must be defined in the translation unit if it
is odr-used. Also note that classes with linkage may contain members whose types do not have linkage, and
that typedef names are ignored in the determination of whether a type has linkage.
— end note ]
30) A class template has the linkage of the innermost enclosing class or namespace in which it is declared.
§ 6.5
47
[ Example:
template <class T> struct B {
void g(T) { }
void h(T);
friend void i(B, T) { }
};
void f() {
struct A { int x; };
// no linkage
A a = { 1 };
B<A> ba;
// declares B<A>::g(A) and B<A>::h(A)
ba.g(a);
// OK
ba.h(a);
// error: B<A>::h(A) not defined in the translation unit
i(ba, a);
// OK
}
— end example ]
10
Two names that are the same (Clause 6) and that are declared in different scopes shall denote the same
variable, function, type, template or namespace if
(10.1)
—
both names have external linkage or else both names have internal linkage and are declared in the same
translation unit; and
(10.2)
—
both names refer to members of the same namespace or to members, not by inheritance, of the same
class; and
(10.3)
—
when both names denote functions, the parameter-type-lists of the functions (11.3.5) are identical; and
(10.4)
—
when both names denote function templates, the signatures (17.6.6.1) are the same.
11
After all adjustments of types (during which typedefs (10.1.3) are replaced by their definitions), the types
specified by all declarations referring to a given variable or function shall be identical, except that declarations
for an array object can specify array types that differ by the presence or absence of a major array bound (11.3.4).
A violation of this rule on type identity does not require a diagnostic.
12
[ Note: Linkage to non-C++ declarations can be achieved using a linkage-specification (10.5).
— end note ]
6.6
Memory and objects
[basic.memobj]
6.6.1
Memory model
[intro.memory]
1
The fundamental storage unit in the C++ memory model is the byte. A byte is at least large enough to contain
any member of the basic execution character set (5.3) and the eight-bit code units of the Unicode UTF-8
encoding form and is composed of a contiguous sequence of bits,31 the number of which is implementation-
defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order
bit. The memory available to a C++ program consists of one or more sequences of contiguous bytes. Every
byte has a unique address.
2
[ Note: The representation of types is described in 6.7.
— end note ]
3
A memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having
nonzero width. [ Note: Various features of the language, such as references and virtual functions, might involve
additional memory locations that are not accessible to programs but are managed by the implementation.
— end note ] Two or more threads of execution (6.8.2) can access separate memory locations without interfering
with each other.
4
[ Note: Thus a bit-field and an adjacent non-bit-field are in separate memory locations, and therefore can be
concurrently updated by two threads of execution without interference. The same applies to two bit-fields,
if one is declared inside a nested struct declaration and the other is not, or if the two are separated by a
zero-length bit-field declaration, or if they are separated by a non-bit-field declaration. It is not safe to
concurrently update two bit-fields in the same struct if all fields between them are also bit-fields of nonzero
width.
— end note ]
5
[ Example: A structure declared as
struct {
char a;
31) The number of bits in a byte is reported by the macro CHAR_BIT in the header <climits>.
§ 6.6.1
48
int b:5,
c:11,
:0,
d:8;
struct {int ee:8;} e;
}
contains four separate memory locations: The member a and bit-fields d and e.ee are each separate memory
locations, and can be modified concurrently without interfering with each other. The bit-fields b and c
together constitute the fourth memory location. The bit-fields b and c cannot be concurrently modified, but
b and a, for example, can be.
— end example ]
6.6.2
Object model
[intro.object]
1
The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is
created by a definition (6.1), by a new-expression (8.5.2.4), when implicitly changing the active member of
a union (12.3), or when a temporary object is created (7.4, 15.2). An object occupies a region of storage
in its period of construction (15.7), throughout its lifetime (6.6.3), and in its period of destruction (15.7).
[ Note: A function is not an object, regardless of whether or not it occupies storage in the way that objects
do.
— end note ] The properties of an object are determined when the object is created. An object can have
a name (Clause 6). An object has a storage duration (6.6.4) which influences its lifetime (6.6.3). An object
has a type (6.7). Some objects are polymorphic (13.3); the implementation generates information associated
with each such object that makes it possible to determine that object’s type during program execution. For
other objects, the interpretation of the values found therein is determined by the type of the expressions (8.5)
used to access them.
2
Objects can contain other objects, called subobjects. A subobject can be a member subobject (12.2), a base
class subobject (Clause 13), or an array element. An object that is not a subobject of any other object is
called a complete object. If an object is created in storage associated with a member subobject or array
element e (which may or may not be within its lifetime), the created object is a subobject of e’s containing
object if:
(2.1)
—
the lifetime of e’s containing object has begun and not ended, and
(2.2)
—
the storage for the new object exactly overlays the storage location associated with e, and
(2.3)
—
the new object is of the same type as e (ignoring cv-qualification).
[ Note: If the subobject contains a reference member or a const subobject, the name of the original subobject
cannot be used to access the new object (6.6.3).
— end note ] [ Example:
struct X { const int n; };
union U { X x; float f; };
void tong() {
U u = {{ 1 }};
u.f = 5.f;
// OK, creates new subobject of u (12.3)
X *p = new (&u.x) X {2};
// OK, creates new subobject of u
assert(p->n == 2);
// OK
assert(*std::launder(&u.x.n) == 2);
// OK
assert(u.x.n == 2);
// undefined behavior, u.x does not name new subobject
}
— end example ]
3
If a complete object is created (8.5.2.4) in storage associated with another object e of type “array of N
unsigned char” or of type “array of N std::byte” (21.2.1), that array provides storage for the created
object if:
(3.1)
—
the lifetime of e has begun and not ended, and
(3.2)
—
the storage for the new object fits entirely within e, and
(3.3)
—
there is no smaller array object that satisfies these constraints.
[ Note: If that portion of the array previously provided storage for another object, the lifetime of that object
ends because its storage was reused (6.6.3).
— end note ] [ Example:
§ 6.6.2
49
template<typename ...T>
struct AlignedUnion {
alignas(T...) unsigned char data[max(sizeof(T)...)];
};
int f() {
AlignedUnion<int, char> au;
int *p = new (au.data) int;
// OK, au.data provides storage
char *c = new (au.data) char();
// OK, ends lifetime of *p
char *d = new (au.data + 1) char();
return *c + *d; // OK
}
struct A { unsigned char a[32]; };
struct B { unsigned char b[16]; };
A a;
B *b = new (a.a + 8) B;
// a.a provides storage for *b
int *p = new (b->b + 4) int;
// b->b provides storage for *p
// a.a does not provide storage for *p (directly),
// but *p is nested within a (see below)
— end example ]
4
An object a is nested within another object b if:
(4.1)
—
a is a subobject of b, or
(4.2)
—
b provides storage for a, or
(4.3)
—
there exists an object c where a is nested within c, and c is nested within b.
5
For every object x, there is some object called the complete object of x, determined as follows:
(5.1)
—
If x is a complete object, then the complete object of x is itself.
(5.2)
—
Otherwise, the complete object of x is the complete object of the (unique) object that contains x.
6
If a complete object, a data member (12.2), or an array element is of class type, its type is considered the
most derived class, to distinguish it from the class type of any base class subobject; an object of a most
derived class type or of a non-class type is called a most derived object.
7
Unless it is a bit-field (12.2.4), a most derived object shall have a nonzero size and shall occupy one or more
bytes of storage. Base class subobjects may have zero size. An object of trivially copyable or standard-layout
type (6.7) shall occupy contiguous bytes of storage.
8
Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address
of the first byte it occupies. Two objects a and b with overlapping lifetimes that are not bit-fields may have
the same address if one is nested within the other, or if at least one is a base class subobject of zero size and
they are of different types; otherwise, they have distinct addresses.32 [ Example:
static const char test1 = ’x’;
static const char test2 = ’x’;
const bool b = &test1 != &test2;
// always true
— end example ]
9
[ Note: C++ provides a variety of fundamental types and several ways of composing new types from existing
types (6.7).
— end note ]
6.6.3
Object lifetime
[basic.life]
1
The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have
non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a
constructor other than a trivial default constructor. [ Note: Initialization by a trivial copy/move constructor
is non-vacuous initialization.
— end note ] The lifetime of an object of type T begins when:
(1.1)
—
storage with the proper alignment and size for type T is obtained, and
(1.2)
—
if the object has non-vacuous initialization, its initialization is complete,
32) Under the “as-if” rule an implementation is allowed to store two objects at the same machine address or not store an object
at all if the program cannot observe the difference (6.8.1).
§ 6.6.3
50
except that if the object is a union member or subobject thereof, its lifetime only begins if that union member
is the initialized member in the union (11.6.1, 15.6.2), or as described in 12.3. The lifetime of an object o of
type T ends when:
(1.3)
—
if T is a class type with a non-trivial destructor (15.4), the destructor call starts, or
(1.4)
—
the storage which the object occupies is released, or is reused by an object that is not nested within
o (6.6.2).
2
The lifetime of a reference begins when its initialization is complete. The lifetime of a reference ends as if it
were a scalar object.
3
[ Note: 15.6.2 describes the lifetime of base and member subobjects.
— end note ]
4
The properties ascribed to objects and references throughout this document apply for a given object or
reference only during its lifetime. [Note: In particular, before the lifetime of an object starts and after its
lifetime ends there are significant restrictions on the use of the object, as described below, in 15.6.2 and
in 15.7. Also, the behavior of an object under construction and destruction might not be the same as the
behavior of an object whose lifetime has started and not ended. 15.6.2 and 15.7 describe the behavior of
objects during the construction and destruction phases.
— end note ]
5
A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly
calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type
with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage
which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a
delete-expression (8.5.2.5) is not used to release the storage, the destructor shall not be implicitly called and
any program that depends on the side effects produced by the destructor has undefined behavior.
6
Before the lifetime of an object has started but after the storage which the object will occupy has been
allocated33 or, after the lifetime of an object has ended and before the storage which the object occupied is
reused or released, any pointer that represents the address of the storage location where the object will be or
was located may be used but only in limited ways. For an object under construction or destruction, see 15.7.
Otherwise, such a pointer refers to allocated storage (6.6.4.4.1), and using the pointer as if the pointer were
of type void*, is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may
only be used in limited ways, as described below. The program has undefined behavior if:
—
(6.1)
the object will be or was of a class type with a non-trivial destructor and the pointer is used as the
operand of a delete-expression,
(6.2)
—
the pointer is used to access a non-static data member or call a non-static member function of the
object, or
(6.3)
—
the pointer is implicitly converted (7.11) to a pointer to a virtual base class, or
(6.4)
—
the pointer is used as the operand of a static_cast (8.5.1.9), except when the conversion is to pointer
to cv void, or to pointer to cv void and subsequently to pointer to cv char, cv unsigned char, or
cv std::byte (21.2.1), or
(6.5)
—
the pointer is used as the operand of a dynamic_cast (8.5.1.7).
[ Example:
#include <cstdlib>
struct B {
virtual void f();
void mutate();
virtual ~B();
};
struct D1 : B { void f(); };
struct D2 : B { void f(); };
void B::mutate() {
new (this) D2;
// reuses storage — ends the lifetime of *this
f();
// undefined behavior
33) For example, before the construction of a global object that is initialized via a user-provided constructor (15.7).
§ 6.6.3
51
|
|