______________________________________________________________________
3 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 notion of an lvalue. 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 termi
nating a program are discussed. Finally, this clause presents the
fundamental types of the language and lists the ways of constructing
compound types from these.
2 This clause does not cover concepts that affect only a single part of
the language. Such concepts are discussed in the relevant clauses. ]
3 An entity is a value, object, subobject, base class subobject, array
element, variable, function, instance of a function, enumerator, type,
class member, template, or namespace.
4 A name is a use of an identifier (_lex.name_) that denotes an entity
or label (_stmt.goto_, _stmt.label_). A variable is introduced by the
declaration of an object. The variable's name denotes the object.
5 Every name that denotes an entity is introduced by a declaration.
Every name that denotes a label is introduced either by a goto state
ment (_stmt.goto_) or a labeled-statement (_stmt.label_).
6 Some names denote types, classes, enumerations, or templates. In gen
eral, it is necessary to determine whether or not a name denotes one
of these entities before parsing the program that contains it. The
process that determines this is called name lookup (_basic.lookup_).
7 Two names are the same if
--they are identifiers composed of the same character sequence; or
--they are the names of overloaded operator functions formed with the
same operator; or
--they are the names of user-defined conversion functions formed with
the same type.
8 An identifier used in more than one translation unit can potentially
refer to the same entity in these translation units depending on the
linkage (_basic.link_) of the identifier specified in each translation
unit.
3.1 Declarations and definitions [basic.def]
1 A declaration (_dcl.dcl_) introduces names into a translation unit or
redeclares names introduced by previous declarations. A declaration
specifies the interpretation and attributes of these names.
2 A declaration is a definition unless it declares a function without
specifying the function's body (_dcl.fct.def_), it contains the extern
specifier (_dcl.stc_) and neither an initializer nor a function-body,
it declares a static data member in a class declaration
(_class.static_), it is a class name declaration (_class.name_), or it
is a typedef declaration (_dcl.typedef_), a using declaration(_names
pace.udecl_), or a using directive(_namespace.udir_).
3 [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
struct X { // defines X
int x; // defines nonstatic 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 N::d
--end example]
4 [Note: in some circumstances, C++ implementations implicitly define
the default constructor (_class.ctor_), copy constructor
(_class.copy_), assignment operator (_class.copy_), or destructor
(_class.dtor_) member functions. [Example: given
struct C {
string s; // string is the standard library class (_lib.string_)
};
int main()
{
C a;
C b = a;
b = a;
}
the implementation will implicitly define functions to make the
definition of C equivalent to
struct C {
string s;
C(): s() { }
C(const C& x): s(x.s) { }
C& operator=(const C& x) { s = x.s; return *this; }
~C() { }
};
--end example] --end note]
5 [Note: a class name can also be implicitly declared by an elaborated-
type-specifier (_basic.scope.pdecl_). ]
6 A program is ill-formed if the definition of any object gives the
object an incompletely-defined object type (_basic.types_).
3.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 either it is the operand
of the sizeof operator (_expr.sizeof_), or it is the operand of the
typeid operator and does not designate an lvalue of polymorphic class
type (_expr.typeid_). An object or non-overloaded function is used if
its name appears in a potentially-evaluated expression. A virtual
member function is used if it is not pure. An overloaded function is
used if it is selected by overload resolution when referred to from a
potentially-evaluated expression. [Note: this covers calls to named
functions (_expr.call_), operator overloading (_over_), user-defined
conversions (_class.conv.fct_), allocation function for placement new
(_expr.new_), as well as non-default initialization (_dcl.init_). A
copy constructor is used even if the call is actually elided by the
implementation. ] An allocation or deallocation function for a class
is used by a new expression appearing in a potentially-evaluated
expression as specified in _expr.new_ and _class.free_. A dealloca
tion function for a class is used by a delete expression appearing in
a potentially-evaluated expression as specified in _expr.delete_ and
_class.free_. A copy-assignment function for a class is used by an
implicitly-defined copy-assignment function for another class as spec
ified in _class.copy_. A default constructor for a class is used by
default initialization as specified in _dcl.init_. A constructor for
a class is used as specified in _dcl.init_. A destructor for a class
is used as specified in _class.dtor_.
3 Every program shall contain at least one definition of every function
that is used in that program. That 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
_class.ctor_, _class.dtor_ and _class.copy_). An object that is used
in a program shall be defined and only one definition shall be pro
vided.
4 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 com
plete. [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
--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:
--an object of type T is defined (_basic.def_, _expr.new_), or
--an lvalue-to-rvalue conversion is applied to an lvalue referring to
an object of type T (_conv.lval_), or
--an expression is converted (either implicitly or explicitly) to type
T (_conv_, _expr.type.conv_, _expr.dynamic.cast_,
_expr.static.cast_, _expr.cast_), or
--an expression is converted to the type pointer to T or reference to
T using an implicit conversion (_conv_), a dynamic_cast
(_expr.dynamic.cast_) or a static_cast (_expr.static.cast_), or
--a class member access operator is applied to an object expression of
type T (_expr.ref_), or
--the typeid operator (_expr.typeid_) or the sizeof operator
(_expr.sizeof_) is applied to an operand of type T, or
--a function with a return type or argument type of type T is defined
(_basic.def_) or called (_expr.call_), or
--an lvalue of type T is assigned to (_expr.ass_). ]
5 There can be more than one definition of a class type (_class_), enu
meration type (_dcl.enum_), inline function with external linkage
(_dcl.fct.spec_), class template (_temp_), non-static function tem
plate (_temp.fct_), static data member of a class template
(_temp.static_), member function template (_temp.mem.func_), or tem
plate specialization for which some template parameters are not speci
fied (_temp.spec_, _temp.class.spec_) 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
--each definition of D shall consist of the same sequence of tokens;
and
--in each definition of D, corresponding names, looked up according to
_basic.lookup_, shall refer to an entity defined within the defini
tion of D, or shall refer to the same entity, after overload resolu
tion (_over.match_) and after matching of partial template special
ization (_temp.over_), except that a name can refer to a const
object with internal or no linkage if the object has the same inte
gral or enumeration type in all definitions of D, and the object is
initialized with a constant expression (_expr.const_), and the value
(but not the address) of the object is used, and the object has the
same value in all definitions of D; and
--in each definition of D, the overloaded operators referred to, the
implicit calls to conversion operators, 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
--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 three requirements described above (and, if the
default argument has sub-expressions with default arguments, this
requirement applies recursively).1)
--if D is a class with an implicitly-declared constructor
(_class.ctor_), it is as if the constructor was implicitly defined
in every translation unit where it is used, and the implicit defini
tion in every translation unit shall call the same constructor for a
base class or a class member of D. [Example:
// translation unit 1:
struct X {
X(int);
X(int, int);
};
X::X(int = 0) { }
class D: public X { };
D d2; // X(int) called by D()
// translation unit 2:
struct X {
X(int);
X(int, int);
};
X::X(int = 0, int = 0) { }
class D: public X { }; // X(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 last four requirements from the list
above shall apply to names from the template's enclosing scope used
in the template definition (_temp.nondep_), and also to dependent
names at the point of instantiation (_temp.dep_). If the defini
tions of D satisfy all these requirements, then the program shall
behave as if there were a single definition of D. If the defini
tions of D do not satisfy these requirements, then the behavior is
undefined.
_________________________
1) _dcl.fct.default_ describes how default argument names are looked
up.
3.3 Declarative regions and scopes [basic.scope]
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 par
ticular name is valid only within some possibly discontiguous portion
of program text called its scope. To determine the scope of a decla
ration, it is sometimes convenient to refer to the potential scope of
a declaration. The scope of a declaration is the same as its poten
tial 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 decla
ration of i. The scope of the second declaration of j is the same as
its potential scope. ]
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 (_class.friend_), certain uses of the elaborated-type-speci
fier (_basic.scope.pdecl_), and using-directives (_namespace.udir_)
alter this general behavior.
4 [Note: the name look up rules are summarized in _basic.lookup_. ]
3.3.1 Point of declaration [basic.scope.pdecl]
1 The point of declaration for a name is immediately after its complete
declarator (_dcl.decl_) and before its initializer (if any), except as
noted below. [Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value.
]
2 [Note: a nonlocal name remains visible up to the point of declaration
of the local name that hides it. [Example:
const int i = 2;
{ int i[i]; }
declares a local array of two integers. ] ]
3 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. ]
4 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]
5 The point of declaration of a class first declared in an elaborated-
type-specifier is as follows:
--for an elaborated-type-specifier of the form
class-key identifier ;
the elaborated-type-specifier declares the identifier to be a class-
name in the scope that contains the declaration, otherwise
--for an elaborated-type-specifier of the form
class-key identifier
the identifier is declared as a class-name in the smallest non-
class, non-function prototype scope that contains the declaration.
[Note: if the class-key is enum, the identifier must refer to an
already declared enum-name. If the identifier in the elaborated-
type-specifier is a qualified-id, it must refer to an already
declared class-name or enum-name. See _basic.lookup.elab_. ]
6 [Note: friend declarations refer to functions or classes that are mem
bers of the nearest enclosing namespace, but they do not introduce new
names into that namespace (_namespace.memdef_). ]
7 [Note: For point of instantiation of a template, see _temp.inst_. ]
3.3.2 Local scope [basic.scope.local]
1 A name declared in a block (_stmt.block_) is local to that block. Its
potential scope begins at its point of declaration
(_basic.scope.pdecl_) and ends at the end of its declarative region.
2 The potential scope of a function parameter name in a function defini
tion (_dcl.fct.def_) begins at its point of declaration and ends at
the end of the outermost block of the function definition. A parame
ter name shall not be redeclared in the outermost block of the func
tion definition.
3 The name in a catch exception-declaration is local to the handler and
shall not be redeclared in the outermost block of the handler.
4 Names declared in the for-init-statement, 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 _stmt.select_.
3.3.3 Function prototype scope [basic.scope.proto]
1 In a function declaration, or in any function declarator except the
declarator of a function definition (_dcl.fct.def_), names of parame
ters (if supplied) have function prototype scope, which terminates at
the end of the nearest enclosing function declarator.
3.3.4 Function scope
1 Labels (_stmt.label_) have function scope and may be used anywhere in
the function in which they are declared. Only labels have function
scope.
3.3.5 Namespace scope [basic.scope.namespace]
1 The declarative region of a namespace-definition is its namespace-
body. The potential scope denoted by an original-namespace-name is
the concatenation of the declarative regions established by each of
the namespace-definitions in the same declarative region with that
original-namespace-name. 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 names
pace scope. Its potential scope includes its namespace from the
name's point of declaration (_basic.scope.pdecl_) onwards, as well as
the potential scope of any using directive (_namespace.udir_) that
nominates its namespace. [Example:
namespace N {
int i;
int g(int a) { return a; }
int k();
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 k(); // ok: duplicate function declaration
int k() // ok: definition of N::k()
{
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 resolu
tion operator (_expr.prim_) applied to the name of its namespace; see
_namespace.qual_.
3 A name declared outside all named or unnamed namespaces (_basic.names
pace_), blocks (_stmt.block_) and classes (_class_) has global names
pace scope (also called global scope). The potential scope of such a
name begins at its point of declaration (_basic.scope.pdecl_) and ends
at the end of the translation unit that is its declarative region.
Names declared in the global namespace scope are said to be global.
3.3.6 Class scope [basic.scope.class]
1 The following rules describe the scope of names declared in classes.
1)The potential scope of a name declared in a class consists not only
of the declarative region following the name's declarator, but also
of all function bodies, default arguments, and constructor ctor-ini
tializers in that class (including such things in nested classes).
2)A name N used in a class S shall refer to the same declaration when
re-evaluated in its context and in the completed scope of S.
3)If reordering member declarations in a class yields an alternate
valid program under (1) and (2), the program's behavior is ill-
formed, no diagnostic is required.
4)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 func
tion's class.
5)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 out
side the class (this includes static data member definitions, nested
class definitions and member function definitions (that is, the
parameter-declaration-clause including default arguments
(_dcl.fct.default_), the member function body and, for constructor
functions (_class.ctor_), the ctor-initializer (_class.base.init_)).
[Example:
typedef int c;
enum { i = 1 };
class X {
char v[i]; // error: 'i' refers to ::i
// but when reevaluated is X::i
int f() { return sizeof(c); } // okay: 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;
};
--end example]
2 The name of a class member shall only be used as follows:
--in the scope of its class (as described above) or a class derived
(_class.derived_) from its class,
--after the . operator applied to an expression of the type of its
class (_expr.ref_) or a class derived from its class,
--after the -> operator applied to a pointer to an object of its class
(_expr.ref_) or a class derived from its class,
--after the :: scope resolution operator (_expr.prim_) applied to the
name of its class or a class derived from its class,
--or after a using declaration (_namespace.udecl_).
3 [Note: the scope of names introduced by friend declarations is
described in _basic.scope.pdecl_. ]
3.3.7 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 (_class.member.lookup_).
2 A class name (_class.name_) or enumeration name (_dcl.enum_) can be
hidden by the name of an object, function, or enumerator declared in
the same scope. If a class or enumeration name and an object, func
tion, or enumerator are declared in the same scope (in any order) with
the same name, the class or enumeration name is hidden wherever the
object, function, or enumerator name is visible.
3 In a member function definition, the declaration of a local name hides
the declaration of a member of the class with the same name; see
_basic.scope.class_. The declaration of a member in a derived class
(_class.derived_) hides the declaration of a member of a base class of
the same name; see _class.member.lookup_.
4 If a name is in scope and is not hidden it is said to be visible.
3.4 Name look up [basic.lookup]
1 The name look up rules apply uniformly to all names (including type
def-names (_dcl.typedef_), namespace-names (_basic.namespace_) and
class-names (_class.name_)) wherever the grammar allows such names in
the context discussed by a particular rule. Name look up associates
the use of a name with a declaration (_basic.def_) of that name. Name
look up shall find an unambiguous declaration for the name (see
_class.member.lookup_). Name look up may associate more than one dec
laration with a name if it finds the name to be a function name; the
declarations are said to form a set of overloaded functions
(_over.load_). Overload resolution (_over.match_) takes place after
name look up has succeeded. The access rules (_class.access_) are
considered only once name look up and function overload resolution (if
applicable) have succeeded. Only after name look up, function over
load resolution (if applicable) and access checking have succeeded are
the attributes introduced by the name's declaration used further in
expression processing (_expr_).
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 [Note: _basic.link_ discusses linkage issues. The notions of scope,
point of declaration and name hiding are discussed in _basic.scope_.
]
3.4.1 Unqualified name look up [basic.lookup.unqual]
1 In all the cases listed in this subclause, the scopes are searched for
a declaration in the order listed in each of the respective category;
name look up 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
_namespace.udir_. For the purpose of the unqualified name look up
rules described in this subclause, the declarations from the namespace
nominated by the using-directive are considered members of the enclos
ing namespace.
3 The lookup for an unqualified name used as the postfix-expression of a
function call is described in _basic.lookup.koenig_. [Note: for pur
poses of determining (during parsing) whether an expression is a post
fix-expression for a function call, the usual name lookup rules apply.
The rules in _basic.lookup.koenig_ have no effect on the syntactic
interpretation of an expression. For example,
typedef int f;
struct A {
friend void f(A &);
operator int();
void g(A a) {
f(a);
}
};
The expression f(a) is a cast-expression equivalent to int(a).
Because the expression is not a function call, the argument-dependent
name lookup (_basic.lookup.koenig_) does not apply and the friend
function f is not found. ]
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 names
pace or before its use in a namespace enclosing its namespace.
6 A name used in the definition of a function2) that is a member of
namespace N (where, only for the purpose of exposition, N could repre
sent the global scope) shall be declared before its use in the block
in which it is used or in one of its enclosing blocks (_stmt.block_)
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) function 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]
7 A name used in the definition of a class X outside of a member func
tion body or nested class definition3) shall be declared in one of the
following ways:
_________________________
2) This refers to unqualified names following the function declarator;
such a name may be used as a type or as a default argument name in the
parameter-declaration-clause, or may be used in the function body.
3) 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 defi
nition.
--before its use in class X or be a member of a base class of X
(_class.member.lookup_), or
--if X is a nested class of class Y (_class.nest_), before the defini
tion of X in Y, or shall be a member of a base class of Y (this look
up applies in turn to Y's enclosing classes, starting with the
innermost enclosing class),4) or
--if X is a local class (_class.local_) 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
--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 defi
nition of class X in namespace N or in one of N's enclosing names
paces.
[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 _names
pace.memdef_. ] [Note: _basic.scope.class_ further describes the
restrictions on the use of names in a class definition. _class.nest_
further describes the restrictions on the use of names in nested class
definitions. _class.local_ further describes the restrictions on the
use of names in local class definitions. ]
8 A name used in the definition of a function that is a member function
(_class.mfct_)5) of class X shall be declared in one of the following
_________________________
4) This look up 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 (_class.nest_).
5) That is, an unqualified name following the function declarator;
such a name may be used as a type or as a default argument name in the
parameter-declaration-clause, or may be used in the function body, or,
if the function is a constructor, may be used in the expression of a
ways:
--before its use in the block in which it is used or in an enclosing
block (_stmt.block_), or
--shall be a member of class X or be a member of a base class of X
(_class.member.lookup_), or
--if X is a nested class of class Y (_class.nest_), shall be a member
of Y, or shall be a member of a base class of Y (this look up
applies in turn to Y's enclosing classes, starting with the inner
most enclosing class),6) or
--if X is a local class (_class.local_) 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
--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 member
function definition, in namespace N or in one of N's enclosing named
namespaces.
[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) function 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: _class.mfct_ and _class.static_ further
describe the restrictions on the use of names in member function defi
nitions. _class.nest_ further describes the restrictions on the use
of names in the scope of nested classes. _class.local_ further
describes the restrictions on the use of names in local class defini
tions. ]
_________________________
mem-initializer.
6) This look up 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.
9 Name look up for a name used in the definition of a friend function
(_class.friend_) defined inline in the class granting friendship shall
proceed as described for look up in member function definitions. If
the friend function is not defined in the class granting friendship,
name look up in the friend function definition shall proceed as
described for look up in namespace member function definitions.
10During the lookup for a name used as a default argument
(_dcl.fct.default_) in a function parameter-declaration-clause or used
in the expression of a mem-initializer for a constructor
(_class.base.init_), 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: _dcl.fct.default_ further
describes the restrictions on the use of names in default arguments.
_class.base.init_ further describes the restrictions on the use of
names in a ctor-initializer. ]
11A name used in the definition of a static member of class X
(_class.static.data_) (after the qualified-id of the static member) is
looked up as if the name was used in a member function of X. [Note:
_class.static.data_ further describes the restrictions on the use of
names in the definition of a static data member. ]
12A name used in the handler for a function-try-block (_except_) is
looked up as if the name was used in the outermost block of the func
tion definition. In particular, the function parameter names shall
not be redeclared in the exception-declaration or 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.
13[Note: the rules for name look up in template definitions are
described in _temp.res_. ]
3.4.2 Argument-dependent name lookup [basic.lookup.koenig]
1 When an unqualified name is used as the postfix-expression in a func
tion call (_expr.call_), other namespaces not considered during the
usual unqualified look up (_basic.lookup.unqual_) may be searched;
this search depends on the types of the arguments.
2 For each argument type T in the function call, there may be a set of
zero or more associated namespaces to be considered; such namespaces
are determined in the following way:
--If T is a fundamental type, its associated set of namespaces is
empty.
--If T is a class type, its associated namespaces are the namespaces
in which the class and its direct and indirect base classes are
defined.
--If T is a union or enumeration type, its associated namespace is the
namespace in which it is defined.
--If T is a pointer to U, a reference to U, or an array of U, its
associated namespaces are the namespaces associated with U.
--If T is a pointer to function type, its associated namespaces are
the namespaces associated with the function parameter types and the
namespaces associated with the return type.
--If T is a pointer to a member function of a class X, its associated
namespaces are the namespaces associated with the function parameter
types and return type, together with the namespaces associated with
X.
--If T is a pointer to a data member of class X, its associated names
paces are the namespaces associated with the member type together
with the namespaces associated with X.
--If T is a template-id, its associated namespaces are the namespace
of the template and the namespaces associated with the type of tem
plate arguments.
If the ordinary unqualified lookup of the name finds the declaration
of a member function, the associated namespaces are not considered.
Otherwise the set of names found by the lookup of the function name is
the union of the set of names found using ordinary unqualified lookup
and the set of names found in the namespaces associated with the argu
ment types.
3 When considering an associated namespace, the lookup is the same as
the lookup performed when the associated namespace is used as a quali
fier (_namespace.qual_) except that using-directives in the associated
namespace are ignored.
+------- BEGIN BOX 1 -------+
This is not exactly what was specified in the paper, but according to
John Wilkinson it was the intent that members continue to hide non-
members. This is probably not quite right. The associated namespaces
should probably be treated as if they were temporarily made searchable
through using directives, with or without the "using directive clo
sure" normally used in such lookups. This would prevent names from
non-namespace scopes (e.g. base class members) from being inaccessible
due to ambiguities with names declared in namespaces. -- Bill Gibbons
+------- END BOX 1 -------+
3.4.3 Qualified name look up [basic.lookup.qual]
1 The name of a class or namespace member can be referred to after the
:: scope resolution operator (_expr.prim_) applied to a nested-name-
specifier that nominates its class or namespace. During the look up
for a name preceding the :: scope resolution operator, object, func
tion, and enumerator names are ignored. If the name found is not a
class-name (_class_) or namespace-name (_namespace.def_), the program
is ill-formed. [Example:
class A {
public:
static int n;
};
int main()
{
int A;
A::n = 42; // OK
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 (_class.nest_) or members of nested
namespaces. ]
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];
// not to: C::X C::arr[C::number];
--end example]
4 A name prefixed by the unary scope operator :: (_expr.prim_) 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 direc
tive (_namespace.qual_). The use of :: allows a global name to be
referred to even if its identifier has been hidden (_basic.scope.hid
ing_).
5 A nested-name-specifier that names a scalar type, followed by ::, fol
lowed by ~type-name is a pseudo-destructor-name for a scalar type
(_expr.pseudo_). The type-name is looked up as a type in the scope of
the nested-name-specifier. [Example:
struct A {
typedef int I;
};
typedef int I1, I2;
extern int* p;
extern int* q;
p->A::I::~I(); // I is looked up in the scope of A
q->I1::~I2(); // I2 is looked up in the scope of
// the postfix-expression
--end example] [Note: _basic.lookup.classref_ describes how name look
up proceeds after the . and -> operators. ]
3.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 (_class.member.lookup_). The name shall represent
a member of that class or a member of one or more members of that
class or of one of its base classes (_class.derived_). [Note: a class
member can be referred to using a qualified-id as soon as the member
point of declaration (_basic.scope.pdecl_) in the class member-speci
fication has been encountered. ]
2 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.
3.4.3.2 Namespace members [namespace.qual]
1 If the nested-name-specifier of a qualified-id nominates a namespace,
the name specified after the nested-name-specifier is looked up in the
scope of the namespace.
2 Given X::m (where X is a user-declared namespace), or given ::m (where
X is the global namespace), let S be the set of all declarations of m
in X and in the transitive closure of all namespaces nominated by
using-directives in X and its used namespaces, except that using-
directives are ignored in any namespace, including X, directly con
taining one or more declarations of m. No namespace is searched more
than once in the lookup of a name. If S is the empty set, the program
is ill-formed. Otherwise, if S has exactly one member, or if the con
text of the reference is a using-declaration (_namespace.udecl_), S 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, the pro
gram 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);
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(float) } and overload
// resolution chooses Z::h(float)
}
3 The same declaration found more than once is not an ambiguity (because
it is still a unique declaration). For 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 }
}
namespace D {
using A::a;
}
namespace BD {
using namespace B;
using namespace D;
}
void g()
{
BD::a++; // ok: S is { A::a, A::a }
}
4 Because each referenced namespace is searched at most once, the fol
lowing 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]
5 During the look up of a qualified namespace member name, if the look
up finds more than one declaration of the member, and if one declara
tion introduces a class name or enumeration name and the other decla
rations either introduce the same object, 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]
6 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
nested-name-specifier unqualified-id
the unqualified-id shall name a member of the namespace designated by
the nested-name-specifier. [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 pro
vide 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){} // okay, defines A::B::f1(int)
--end example]
3.4.4 Elaborated type specifiers [basic.lookup.elab]
1 An elaborated-type-specifier may be used to refer to a previously
declared class-name or enum-name even though the name has been hidden
by an object, function, or enumerator declaration (_basic.scope.hid
ing_). The class-name or enum-name in the elaborated-type-specifier
may either be a simple identifer or be a qualified-id.
2 If the name in the elaborated-type-specifier is a simple identifer,
and unless the elaborated-type-specifier has the following form:
class-key identifier ;
the identifier is looked up according to _basic.lookup.unqual_ but
ignoring any objects, functions or enumerators that have been
declared. If this name look up finds a typedef-name, the elaborated-
type-specifier is ill-formed. If the elaborated-type-specifier refers
to an enum-name and this look up does not find a previously declared
enum-name, the elaborated-type-specifier is ill-formed. If the elabo
rated-type-specifier refers to an class-name and this look up does not
find a previously declared class-name, or if the elaborated-type-spec
ifier has the form:
class-key identifier ;
the elaborated-type-specifier is a declaration that introduces the
class-name as described in _basic.scope.pdecl_.
3 If the name is a qualified-id, the name is looked up according its
qualifications, as described in _basic.lookup.qual_, but ignoring any
objects, functions or enumerators that have been declared. If this
name look up finds a typedef-name, the elaborated-type-specifier is
ill-formed. If this name look up does not find a previously declared
class-name or enum-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
friend struct Glob; // ok: Declares Glob in global scope
/* ... */
};
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 nested Data
};
struct Data; // ok: Redeclares Data at global scope
struct ::Data; // error: cannot introduce a qualified type
struct Base::Data; // error: cannot introduce a qualified type
struct Base::Datum; // error: Datum undefined
struct Base::Data* pBase; // ok: refers to nested Data
--end example]
3.4.5 Class member access [basic.lookup.classref]
1 If the id-expression in a class member access (_expr.ref_) is an
unqualified-id, and the type of the object expression is of a class
type C (or of pointer to a class type C), the unqualified-id is looked
up in the scope of class C. If the type of the object expression is
of pointer to scalar type, the unqualified-id is looked up in the
scope of the object expression.
2 If the unqualified-id is ~type-name, and the type of the object
expression is of a class type C (or of pointer to a class type C), the
type-name is looked up in the context of the entire postfix-expression
and in the scope of class C. The type-name shall refer to a class-
name. If type-name is found in both contexts, the name shall refer to
the same class type. If the type of the object expression is of
scalar type, the type-name is looked up in the scope of the object
expression (_expr.pseudo_).
3 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
looked up both in the context of the entire postfix-expression and in
the scope of the class of the object expression. If the name is found
only in the scope of the class of the object expression, the name
shall refer to a class-name. If the name is found only in the context
of the entire postfix-expression, the name shall refer to a class-name
or namespace-name. If the name is found in both contexts, the class-
name-or-namespace-name shall refer to the same entity. [Note: because
the name of a class is inserted in its class scope (_class_), the name
of a class is also considered a nested member of that class. ]
4 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.
5 If the nested-name-specifier contains a class template-id
(_temp.names_), its template-arguments are evaluated in the context in
which the entire postfix-expression occurs.
6 If the id-expression is a conversion-function-id, its conversion-type-
id shall denote the same type in both the context in which the entire
postfix-expression occurs and in the context of the class of the
object expression (or the class pointed to by the pointer expression).
3.4.6 Using directives and namespace aliases [basic.lookup.udir]
1 When looking up a namespace-name in a using-directive or namespace-
alias-definition, only namespace names are considered.
3.5 Program and linkage [basic.link]
1 A program consists of one or more translation units (_lex_) 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:
--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.
--When a name has internal linkage, the entity it denotes can be
referred to by names from other scopes in the same translation unit.
--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 (_basic.scope.namespace_) has internal
linkage if it is the name of
--an object, function or function template that is explicitly declared
static or,
--an object that is explicitly declared const and neither explicitly
declared extern nor previously declared to have external linkage; or
--the name of a data member of an anonymous union.
4 A name having namespace scope has external linkage if it is the name
of
--an object, unless it has internal linkage; or
--a function, unless it has internal linkage; or
--a named class (_class_), or an unnamed class defined in a typedef
declaration in which the class has the typedef name for linkage pur
poses (_dcl.typedef_); or
--a named enumeration (_dcl.enum_), or an unnamed enumeration defined
in a typedef declaration in which the enumeration has the typedef
name for linkage purposes (_dcl.typedef_); or
--an enumerator belonging to an enumeration with external linkage; or
--a template, unless it is a function template that has internal link
age (_temp_); or
--a namespace (_basic.namespace_), unless it is declared within an
unnamed namespace.
5 In addition, a name of class scope has external linkage if the name of
the class has external linkage.
6 The name of a function declared in a block scope has linkage. If the
block scope function declaration matches a prior visible declaration
of the same function, the function name receives the linkage of the
previous declaration; otherwise, it receives external linkage. The
name of an object declared by a block scope extern declaration has
linkage. If the block scope declaration matches a prior visible dec
laration of the same object, the name introduced by the block scope
declaration receives the linkage of the previous declaration; other
wise, it receives external linkage. [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
}
}
There are three objects named i in this program. The object with
internal linkage introduced by the declaration in global scope (line
//1), the object with automatic storage duration introduced by the
declaration on line //2, and the object with static storage duration
and external linkage introduced by the declaration on line //3. ]
7 Names not covered by these rules have no linkage. Moreover, except as
noted, a name declared in a local scope (_basic.scope.local_) has no
linkage. A name with no linkage (notably, the name of a class or enu
meration declared in a local scope (_basic.scope.local_)) shall not be
used to declare an entity with linkage. If a declaration uses a type
def name, it is the linkage of the type name to which the typedef
refers that is considered. [Example:
void f()
{
struct A { int x; }; // no linkage
extern A a; // ill-formed
typedef A B;
extern B b; // ill-formed
}
--end example] This implies that names with no linkage cannot be used
as template arguments (_temp.arg_).
8 Two names that are the same (_basic_) and that are declared in differ
ent scopes shall denote the same object, reference, function, type,
enumerator, template or namespace if
--both names have external linkage or else both names have internal
linkage and are declared in the same translation unit; and
--both names refer to members of the same namespace or to members, not
by inheritance, of the same class; and
--when both names denote functions, the function types are identical
for purposes of overloading; and
--when both names denote function templates, the signatures
(_temp.over.link_) are the same.
9 After all adjustments of types (during which typedefs (_dcl.typedef_)
are replaced by their definitions), the types specified by all decla
rations of a particular external name 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 (_dcl.array_), and
declarations for functions with the same name can specify different
numbers and types of parameters (_dcl.fct_). A violation of this rule
on type identity does not require a diagnostic.
10[Note: linkage to non-C++ declarations can be achieved using a link
age-specification (_dcl.link_). ]
3.6 Start and termination [basic.start]
3.6.1 Main function [basic.start.main]
1 A program shall contain a global function called main, which is the
designated start of the program. It is implementation-defined whether
a program in a freestanding environment is required to define a main
function. [Note: in a freestanding environment, start-up and termina
tion is implementation-defined; start-up contains the execution of
constructors for objects of namespace scope with static storage dura
tion; termination contains the execution of destructors for objects
with static storage duration. ]
2 An implementation shall not predefine the main function. This func
tion shall not be overloaded. It shall have a return type of type
int, but otherwise its type is implementation-defined. All implemen
tations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
In the latter form argc shall be the number of arguments passed to the
program from the environment in which the program is run. If argc is
nonzero these arguments shall be supplied in argv[0] through
argv[argc-1] as pointers to the initial characters of null-terminated
multibyte strings (NTMBSs) (_lib.multibyte.strings_) and argv[0] shall
be the pointer to the initial character of a NTMBS that represents the
name used to invoke the program or "". The value of argc shall be
nonnegative. The value of argv[argc] shall be 0. [Note: it is recom
mended that any further (optional) parameters be added after argv. ]
3 The function main shall not be called from within a program. The
linkage (_basic.link_) of main is implementation-defined. A program
that takes the address of main, or declares it inline or static is
ill-formed. The name main is not otherwise reserved. [Example: mem
ber functions, classes, and enumerations can be called main, as can
entities in other namespaces. ]
4 Calling the function
void exit(int);
declared in <cstdlib> (_lib.support.start.term_) terminates the pro
gram without leaving the current block and hence without destroying
any objects with automatic storage duration (_class.dtor_). If exit
is called to end a program during the destruction of an object with
static storage duration, the program has undefined behavior.
5 A return statement in main has the effect of leaving the main function
(destroying any objects with automatic storage duration) and calling
exit with the return value as the argument. If control reaches the
end of main without encountering a return statement, the effect is
that of executing
return 0;
3.6.2 Initialization of non-local objects [basic.start.init]
1 The storage for objects with static storage duration
(_basic.stc.static_) shall be zero-initialized (_dcl.init_) before any
other initialization takes place. Objects of POD types
(_basic.types_) with static storage duration initialized with constant
expressions (_expr.const_) shall be initialized before any dynamic
initialization takes place. Objects of namespace scope with static
storage duration defined in the same translation unit and dynamically
initialized shall be initialized in the order in which their defini
tion appears in the translation unit. [Note: _dcl.init.aggr_
describes the order in which aggregate members are initialized. The
initialization of local static objects is described in _stmt.dcl_. ]
2 An implementation is permitted to perform the initialization of an
object of namespace scope with static storage duration as a static
initialization even if such initialization is not required to be done
statically, provided that
--the dynamic version of the initialization does not change the value
of any other object of namespace scope with static storage duration
prior to its initialization, and
--the static version of the initialization produces the same value in
the initialized object as would be produced by the dynamic initial
ization if all objects not required to be initialized statically
were initialized dynamically.
[Note: as a consequence, if the initialization of an object obj1
refers to an object obj2 of namespace scope with static storage dura
tion potentially requiring dynamic initialization and defined later in
the same translation unit, it is unspecified whether the value of obj2
used will be the value of the fully initialized obj2 (because obj2 was
statically initialized) or will be the value of obj2 merely zero-ini
tialized. For example,
inline double fd() { return 1.0; }
extern double d1;
double d2 = d1; // unspecified:
// may be statically initialized to 0.0 or
// dynamically initialized to 1.0
double d1 = fd(); // may be initialized statically to 1.0
--end note]
3 It is implementation-defined whether the dynamic initialization
(_dcl.init_, _class.static_, _class.ctor_, _class.expl.init_) of an
object of namespace scope with static storage duration is done before
the first statement of main or deferred to any point in time after the
first statement of main but before the first use of a function or
object defined in the same translation unit. [Example:
// -- File 1 --
#include "a.h"
#include "b.h"
B b;
A::A(){
b.Use();
}
// -- File 2 --
#include "a.h"
A a;
// -- File 3 --
#include "a.h"
#include "b.h"
extern A a;
extern B b;
main() {
a.Use();
b.Use();
}
It is implementation-defined whether a is defined before main is
entered or whether its definition is delayed until a is first used in
main. It is implementation-defined whether b is defined before main
is entered or whether its definition is delayed until b is first used
in main. In particular, if a is defined before main is entered, it is
not guaranteed that b will be initialized before it is used by the
initialization of a, that is, before A::A is called. ]
4 If construction or destruction of a non-local static object ends in
throwing an uncaught exception, the result is to call terminate
(_lib.terminate_).
3.6.3 Termination [basic.start.term]
1 Destructors (_class.dtor_) for initialized objects of static storage
duration (declared at block scope or at namespace scope) are called
when returning from main and when calling exit (_lib.sup
port.start.term_). These objects are destroyed in the reverse order
of the completion of their constructor or of the completion of their
dynamic initialization. If an object is zero-initialized or initial
ized with a constant-expression, the object is destroyed in the same
order as if the object was dynamically initialized. For an object of
array or class type, all subobjects of that object are destroyed
before any local object with static storage duration initialized dur
ing the construction of the subobjects is destroyed.
2 If a function contains a local object of static storage duration that
has been destroyed and the function is called during the destruction
of an object with static storage duration, the program has undefined
behavior if the flow of control passes through the definition of the
previously destroyed local object.
3 If a function is registered with atexit (see <cstdlib>, _lib.sup
port.start.term_) then following the call to exit, any objects with
static storage duration initialized prior to the registration of that
function will not be destroyed until the registered function is called
from the termination process and has completed. For an object with
static storage duration constructed after a function is registered
with atexit, then following the call to exit, the registered function
is not called until the execution of the object's destructor has com
pleted.
4 Where a C++ implementation coexists with a C implementation, any
actions specified by the C implementation to take place after the
atexit functions have been called take place after all destructors
have been called.
5 Calling the function
void abort();
declared in <cstdlib> terminates the program without executing
destructors for objects of automatic or static storage duration and
without calling the functions passed to atexit().
3.7 Storage duration [basic.stc]
1 Storage duration is the property of an object that defines the minimum
potential lifetime of the storage containing the object. The storage
duration is determined by the construct used to create the object and
is one of the following:
--static storage duration
--automatic storage duration
--dynamic storage duration
2 Static and automatic storage durations are associated with objects
introduced by declarations (_basic.def_). The dynamic storage dura
tion is associated with objects created with operator new
(_expr.new_).
3 The storage class specifiers static and auto are related to storage
duration as described below.
4 References (_dcl.ref_) might or might not require storage; however,
the storage duration categories apply to references as well.
3.7.1 Static storage duration [basic.stc.static]
1 All non-local objects have static storage duration. The storage for
these objects shall last for the duration of the program
(_basic.start.init_, _basic.start.term_).
2 If an object of static storage duration has initialization or a
destructor with side effects, it shall not be eliminated even if it
appears to be unused, except that a class object or its copy may be
eliminated as specified in _class.copy_.
3 The keyword static can be used to declare a local variable with static
storage duration. [Note: _stmt.dcl_ describes the initialization of
local static variables; _basic.start.term_ describes the destruction
of local static variables. ]
4 The keyword static applied to a class data member in a class defini
tion gives the data member static storage duration.
3.7.2 Automatic storage duration [basic.stc.auto]
1 Local objects explicitly declared auto or register or not explicitly
declared static or extern have automatic storage duration. The stor
age for these objects lasts until the block in which they are created
exits.
2 [Note: these objects are initialized and destroyed as described
_stmt.dcl_. ]
3 If a named automatic object has initialization or a destructor with
side effects, it shall not be destroyed before the end of its block,
nor shall it be eliminated as an optimization even if it appears to be
unused, except that a class object or its copy may be eliminated as
specified in _class.copy_.
3.7.3 Dynamic storage duration [basic.stc.dynamic]
1 Objects can be created dynamically during program execution
(_intro.execution_), using new-expressions (_expr.new_), and destroyed
using delete-expressions (_expr.delete_). A C++ implementation pro
vides access to, and management of, dynamic storage via the global
allocation functions operator new and operator new[] and the global
deallocation functions operator delete and operator delete[].
2 The library provides default definitions for the global allocation and
deallocation functions. Some global allocation and deallocation func
tions are replaceable (_lib.new.delete_). A C++ program shall provide
at most one definition of a replaceable allocation or deallocation
function. Any such function definitions replace the default version
provided in the library (_lib.replacement.functions_). The following
allocation and deallocation functions are implicitly declared in a
program
::operator new(size_t)
::operator new[](size_t)
::operator delete(void*)
::operator delete[](void*)
[Note: a new-expression or delete-expression that refers to one of
these functions without including the header <new> is well-formed. ]
Allocation and/or deallocation functions can also be declared and
defined for any class (_class.free_).
3 Any allocation and/or deallocation functions defined in a C++ program
shall conform to the semantics specified in this subclause.
3.7.3.1 Allocation functions [basic.stc.dynamic.allocation]
1 An allocation function shall be a class member function or a global
function; a program is ill-formed if an allocation function is
declared in a namespace scope other than global scope or declared
static in global scope. The return type shall be void*. The first
parameter shall have type size_t (_lib.support.type_). The first
parameter shall not have an associated default argument
(_dcl.fct.default_). The value of the first parameter shall be inter
preted as the requested size of the allocation. An allocation func
tion can be a function template. Such a template shall declare its
return type and first parameter as specified above (that is, template
parameter types shall not be used in the return type and first parame
ter type). Template allocation functions shall have two or more
parameters.
2 The function shall return the address of the start of a block of stor
age whose length in bytes shall be at least as large as the requested
size. There are no constraints on the contents of the allocated stor
age on return from the allocation function. The order, contiguity,
and initial value of storage allocated by successive calls to an allo
cation function is unspecified. The pointer returned shall be suit
ably aligned so that it can be assigned to a pointer of any type and
then used to access the object or array in the storage allocated
(until the storage is explicitly deallocated by a call to a corre
sponding deallocation function). If the size of the space requested
is zero, the value returned shall not be a null pointer value
(_conv.ptr_). The results of dereferencing a pointer returned as a
request for zero size are undefined.7)
3 If an allocation function is unable to obtain an appropriate block of
storage, it can invoke the currently installed new_handler8) and/or
throw an exception (_except_) of class bad_alloc (_lib.bad.alloc_) or
a class derived from bad_alloc.
4 A global allocation function is only called as the result of a new
expression (_expr.new_), or called directly using the function call
syntax (_expr.call_), or called indirectly through calls to the func
tions in the C++ standard library. [Note: in particular, a global
allocation function is never called to allocate storage for objects
with static storage duration (_basic.stc.static_), for objects of type
type_info (_expr.typeid_), for the copy of an object thrown by a throw
expression (_except.throw_). ]
_________________________
7) The intent is to have operator new() implementable by calling mal
loc() or calloc(), so the rules are substantially the same. C++ dif
fers from C in requiring a zero request to return a non-null pointer.
8) A program-supplied allocation function can obtain the address of
the currently installed new_handler (_lib.new.handler_) using the
set_new_handler() function (_lib.set.new.handler_).
3.7.3.2 Deallocation functions [basic.stc.dynamic.deallocation]
1 Deallocation functions shall be class member functions or global func
tions; a program is ill-formed if deallocation functions are declared
in a namespace scope other than global scope or declared static in
global scope.
2 Each deallocation function shall return void and its first parameter
shall be void*. For class member deallocation functions, a second
parameter of type size_t (_lib.support.types_) may be added. If both
versions are declared in the same class, the one-parameter form is the
usual deallocation function and the two-parameter form is used for
placement delete (_expr.new_). If the second version is declared but
not the first, it is the usual deallocation function, not placement
delete. A dellocation function can be a function template. Such a
template shall declare its return type and first parameter as speci
fied above (i.e., template parameter types shall not be used in the
return type and first parameter type). Template deallocation func
tions shall have two or more parameters. However, a template deallo
cation function will never be used to generate the two parameter ver
sion of a member deallocation function (i.e., the one whose second
parameter is of type size_t).
3 The value of the first parameter supplied to a deallocation function
shall be a null pointer value, or refer to storage allocated by the
corresponding allocation function (even if that allocation function
was called with a zero argument). If the value of the first argument
is a null pointer value, the call to the deallocation function has no
effect. If the value of the first argument refers to a pointer
already deallocated, the effect is undefined.
4 If the argument given to a deallocation function is a pointer that is
not the null pointer value (_conv.ptr_), the deallocation function
will deallocate the storage referenced by the pointer and render the
pointer invalid. The value of a pointer that refers to deallocated
storage is indeterminate. The effect of using the value of a pointer
to deallocated storage is undefined.9)
3.7.4 Duration of sub-objects [basic.stc.inherit]
1 The storage duration of member subobjects, base class subobjects and
array elements is that of their complete object (_intro.object_).
3.8 Object Lifetime [basic.life]
1 The lifetime of an object is a runtime property of the object. The
lifetime of an object of type T begins when:
--storage with the proper alignment and size for type T is obtained,
and
_________________________
9) On some implementations, it causes a system-generated runtime
fault.
--if T is a class type with a non-trivial constructor (_class.ctor_),
the constructor call has completed.
The lifetime of an object of type T ends when:
--if T is a class type with a non-trivial destructor (_class.dtor_),
the destructor call starts, or
--the storage which the object occupies is reused or released.
2 [Note: the lifetime of an array object or of an object of POD types
(_basic.types_) starts as soon as storage with proper size and align
ment is obtained, and its lifetime ends when the storage which the
array or object occupies is reused or released. _class.base.init_
describes the lifetime of base and member subobjects. ]
3 The properties ascribed to objects throughout this International Stan
dard apply for a given object 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 _class.base.init_ and in _class.cdtor_.
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. _class.base.init_ and _class.cdtor_ describe
the behavior of objects during the construction and destruction
phases. ]
4 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
(_expr.delete_) 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.
5 Before the lifetime of an object has started but after the storage
which the object will occupy has been allocated10) or, after the life
time of an object has ended and before the storage which the object
occupied is reused or released, any pointer that refers to the storage
location where the object will be or was located may be used but only
in limited ways. Such a pointer refers to allocated storage
(_basic.stc.dynamic.deallocation_), and using the pointer as if the
pointer were of type void*, is well-defined. Such a pointer may be
dereferenced (to initialize a reference, for example) but converting
the resulting lvalue to an rvalue (_conv.lval_) results in undefined
behavior. If the object will be or was of a class type with a non-
_________________________
10) For example, before the construction of a global object of non-POD
class type (_class.cdtor_).
trivial destructor, and the pointer is used as the operand of a
delete-expression, the program has undefined behavior. If the object
will be or was of a non-POD class type, the program has undefined
behavior if:
--the pointer is used to access a non-static data member or call a
non-static member function of the object, or
--the pointer is implicitly converted (_conv.ptr_) to a pointer to a
base class type, or
--the pointer is used as the operand of a static_cast
(_expr.static.cast_) (except when the conversion is to void* or
char*)
--the pointer is used as the operand of a dynamic_cast
(_expr.dynamic.cast_). [Example:
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
... = this; // ok, 'this' points to valid memory
}
void g() {
void* p = malloc(sizeof(D1) + sizeof(D2));
B* pb = new (p) D1;
pb->mutate();
&pb; // ok: pb points to valid memory
void* q = pb; // ok: pb points to valid memory
pb->f(); // undefined behavior, lifetime of *pb has ended
}
--end example]
6 Similarly, before the lifetime of an object has started but after the
storage which the object will occupy has been allocated or, after the
lifetime of an object has ended and before the storage which the
object occupied is reused or released, any reference to the original
object may be used but only in limited ways. Such a reference refers
to allocated storage (_basic.stc.dynamic.deallocation_), and using the
reference as an lvalue (to initialize another reference, for example)
is well-defined. If an lvalue-to-rvalue conversion (_conv.lval_) is
applied to such a reference, the program has undefined behavior; if
the original object will be or was of a non-POD class type, the pro
gram has undefined behavior if:
--the reference is used to access a non-static data member or call a
non-static member function of the object, or
--the reference is used as the operand of a static_cast
(_expr.static.cast_) (except when the conversion is to char&), or
--the reference is used as the operand of a dynamic_cast
(_expr.dynamic.cast_) or as the operand of typeid.
7 If, after the lifetime of an object has ended and before the storage
which the object occupied is reused or released, a new object is cre
ated at the storage location which the original object occupied, a
pointer that pointed to the original object or, a reference that
referred to the original object or, the name of the original object
will automatically refer to the new object and, once the lifetime of
the new object has started, can be used to manipulate the new object,
if:
--the storage for the new object exactly overlays the storage location
which the original object occupied, and
--the new object is of the same type as the original object (ignoring
the top-level cv-qualifiers), and
--the original object was a most derived object (_intro.object_) of
type T and the new object is a most derived object of type T (that
is, they are not base class subobjects). [Example:
struct C {
int i;
void f();
const C& operator=( const C& );
};
const C& C::operator=( const C& other)
{
if ( this != &other )
{
this->~C(); // lifetime of '*this' ends
new (this) C(other); // new object of type C created
f(); // well-defined
}
return *this;
}
C c1;
C c2;
c1 = c2; // well-defined
c1.f(); // well-defined; c1 refers to a new object of type C
--end example]
8 If a program ends the lifetime of an object of type T with static
(_basic.stc.static_) or automatic (_basic.stc.auto_) storage duration
and if T has a non-trivial destructor,11) the program must ensure that
_________________________
11) that is, an object for which a destructor will be called implicit
ly -- either upon exit from the block for an object with automatic
storage duration or upon exit from the program for an object with
static storage duration.
an object of the original type occupies that same storage location
when the implicit destructor call takes place; otherwise the behavior
of the program is undefined. This is true even if the block is exited
with an exception. [Example:
class T { };
struct B {
~B();
};
void h() {
B b;
new (&b) T;
} // undefined behavior at block exit
--end example]
9 Creating a new object at the storage location that a const object with
static or automatic storage duration occupies or, at the storage loca
tion that such a const object used to occupy before its lifetime ended
results in undefined behavior. [Example:
struct B {
B();
~B();
};
const B b;
void h() {
b.~B();
new (&b) const B; // undefined behavior
}
--end example]
3.9 Types [basic.types]
1 [Note: these clauses impose requirements on implementations regarding
the representation of types. There are two kinds of types: fundamen
tal types and compound types. Types describe objects
(_intro.object_), references (_dcl.ref_), or functions (_dcl.fct_). ]
2 For any object type T, whether or not the object holds a valid value
of type T, the underlying bytes (_intro.memory_) making up the object
can be copied into an array of char or unsigned char.12) If the con
tent of the array of char or unsigned char is copied back into the
object, the object shall subsequently hold its original value. [Exam
ple:
_________________________
12) By using, for example, the library functions (_lib.headers_) mem
cpy or memmove.
#define N sizeof(T)
char buf[N];
T obj; // obj initialized to its original value
memcpy(buf, &obj, N);
// between these two calls to memcpy,
// obj might be modified
memcpy(&obj, buf, N);
// at this point, each subobject of obj of scalar type
// holds its original value
--end example]
3 For any POD type T, if two pointers to T point to distinct T objects
obj1 and obj2, if the value of obj1 is copied into obj2, using the
memcpy library function, obj2 shall subsequently hold the same value
as obj1. [Example:
T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of scalar type in *t1p
// contains the same value as the corresponding subobject in
// *t2p
--end example]
4 The object representation of an object of type T is the sequence of N
unsigned char objects taken up by the object of type T, where N equals
sizeof(T). The value representation of an object is the sequence of
bits that hold the value of type T. For POD types, the value repre
sentation is a sequence of bits in the object representation that
determines a value, which is one discrete element of an implementa
tion-defined set of values.13)
5 Object types have alignment requirements (_basic.fundamental_,
_basic.compound_). The alignment of an object type is an implementa
tion-defined integer value representing a number of bytes; an object
is allocated at an address that meets the alignment requirements of
its object type.
6 A class that has been declared but not defined or, an array of unknown
size or of incomplete element type is an incomplete type.14) Also, the
void type is an incomplete type (_basic.fundamental_). Objects shall
not be defined to have an incomplete type. The term incompletely-
defined object type is a synonym for incomplete type; the term com
pletely-defined object type is a synonym for complete type.
7 A class type (such as "class X") might be incomplete at one point in a
translation unit and complete later on; the type "class X" is the same
type at both points. The declared type of an array object might be an
_________________________
13) The intent is that the memory model of C++ is compatible with that
of ISO/IEC 9899 Programming Language C.
14) The size and layout of an instance of an incomplete type is un
known.
array of incomplete class type and therefore incomplete; if the class
type is completed later on in the translation unit, the array type
becomes complete; the array type at those two points is the same type.
The declared type of an array object might be an array of unknown size
and therefore be incomplete at one point in a translation unit and
complete later on; the array types at those two points ("array of
unknown bound of T" and "array of N T") are different types. The type
of a pointer to array of unknown size, or of a type defined by a type
def declaration to be an array of unknown size, cannot be completed.
[Example:
class X; // X is an incomplete type
extern X* xp; // xp is a pointer to an incomplete type
extern int arr[]; // the type of arr is incomplete
typedef int UNKA[]; // UNKA is an incomplete type
UNKA* arrp; // arrp is a pointer to an incomplete type
UNKA** arrpp;
void foo()
{
xp++; // ill-formed: X is incomplete
arrp++; // ill-formed: incomplete type
arrpp++; // okay: sizeof UNKA* is known
}
struct X { int i; }; // now X is a complete type
int arr[10]; // now the type of arr is complete
X x;
void bar()
{
xp = &x; // okay; type is ``pointer to X''
arrp = &arr; // ill-formed: different types
xp++; // okay: X is complete
arrp++; // ill-formed: UNKA can't be completed
}
--end example]
8 [Note: the rules for declarations and expressions describe in which
contexts incomplete types are prohibited. ]
9 An object type is a (possibly cv-qualified) type that is not a func
tion type, not a reference type, and not incomplete (except for an
incompletely-defined object type).
10Arithmetic types (_basic.fundamental_), enumeration types, pointer
types, and pointer to member types (_basic.compound_), and cv-quali
fied versions of these types (_basic.type.qualifier_) are collectively
called scalar types. Scalar types, POD-struct types, POD-union types
(_class_), arrays of such types and cv-qualified versions of these
types (_basic.type.qualifier_) are collectively called POD types.
11If two types T1 and T2 are the same type, then T1 and T2 are layout-
compatible types. [Note: Layout-compatible enumerations are described
in _dcl.enum_. Layout-compatible POD-structs and POD-unions are
described in _class.mem_. ]
3.9.1 Fundamental types [basic.fundamental]
1 Objects declared as characters char) shall be large enough to store
any member of the implementation's basic character set. If a charac
ter from this set is stored in a character object, the integral value
of that character object is equal to the value of the single character
literal form of that character. It is implementation-defined whether
a char object can hold negative values. Characters can be explicitly
declared unsigned or signed. Plain char, signed char, and
unsigned char are three distinct types. A char, a signed char, and an
unsigned char occupy the same amount of storage and have the same
alignment requirements (_basic.types_); that is, they have the same
object representation. For character types, all bits of the object
representation participate in the value representation. For unsigned
character types, all possible bit patterns of the value representation
represent numbers. These requirements do not hold for other types. In
any particular implementation, a plain char object can take on either
the same values as a signed char or an unsigned char; which one is
implementation-defined.
2 There are four signed integer types: "signed char", "short int",
"int", and "long int." In this list, each type provides at least as
much storage as those preceding it in the list. Plain ints have the
natural size suggested by the architecture of the execution
environment15) ; the other signed integer types are provided to meet
special needs.
3 For each of the signed integer types, there exists a corresponding
(but different) unsigned integer type: "unsigned char", "unsigned
short int", "unsigned int", and "unsigned long int," each of which
occupies the same amount of storage and has the same alignment
requirements (_basic.types_) as the corresponding signed integer
type16) ; that is, each signed integer type has the same object repre
sentation as its corresponding unsigned integer type. The range of
nonnegative values of a signed integer type is a subrange of the cor
responding unsigned integer type, and the value representation of each
corresponding signed/unsigned type shall be the same.
4 Unsigned integers, declared unsigned, shall obey the laws of arith
metic modulo 2n where n is the number of bits in the representation of
that particular size of integer.17)
5 Type wchar_t is a distinct type whose values can represent distinct
codes for all members of the largest extended character set specified
_________________________
15) that is, large enough to contain any value in the range of INT_MIN
and INT_MAX, as defined in the header <climits>.
16) See _dcl.type.simple_ regarding the correspondence between types
and the sequences of type-specifiers that designate them.
17) This implies that unsigned arithmetic does not overflow because a
result that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting unsigned integer type.
among the supported locales (_lib.locale_). Type wchar_t shall have
the same size, signedness, and alignment requirements (_intro.memory_)
as one of the other integral types, called its underlying type.
6 Values of type bool are either true or false.18) [Note: there are no
signed, unsigned, short, or long bool types or values. ] As described
below, bool values behave as integral types. Values of type bool par
ticipate in integral promotions (_conv.prom_).
7 Types bool, char, wchar_t, and the signed and unsigned integer types
are collectively called integral types.19) A synonym for integral type
is integer type. The representations of integral types shall define
values by use of a pure binary numeration system.20) [Example: this
International Standard permits 2's complement, 1's complement and
signed magnitude representations for integral types. ]
8 There are three floating point types: float, double, and long double.
The type double provides at least as much precision as float, and the
type long double provides at least as much precision as double. The
set of values of the type float is a subset of the set of values of
the type double; the set of values of the type double is a subset of
the set of values of the type long double. The value representation
of floating-point is implementation-defined. Integral and floating
types are collectively called arithmetic types. Specializations of
the standard template numeric_limits (_lib.support.limits_) shall
specify the maximum and minimum values of each arithmetic types for an
implementation.
9 The void type has an empty set of values. The void type is an incom
plete type that cannot be completed. It is used as the return type
for functions that do not return a value. Any expression can be
explicitly converted to type void (_expr.cast_); the resulting expres
sion shall be used only as an expression statement (_stmt.expr_), as
the left operand of a comma expression (_expr.comma_), or as a second
or third operand of ?: (_expr.cond_).
10[Note: even if the implementation defines two or more basic types to
have the same value representation, they are nevertheless different
types. ]
_________________________
18) Using a bool value in ways described by this International Stan
dard as ``undefined,'' such as by examining the value of an uninitial
ized automatic variable, might cause it to behave as if is neither
true nor false.
19) Therefore, enumerations (_dcl.enum_) are not integral; however,
enumerations can be promoted to int, unsigned int, long, or unsigned
long, as specified in _conv.prom_.
20) A positional representation for integers that uses the binary dig
its 0 and 1, in which the values represented by successive bits are
additive, begin with 1, and are multiplied by successive integral pow
er of 2, except perhaps for the bit with the highest position.
(Adapted from the American National Dictionary for Information Pro
cessing Systems.)
3.9.2 Compound types [basic.compound]
1 Compound types can be constructed from the fundamental types in the
following ways:
--arrays of objects of a given type, _dcl.array_;
--functions, which have parameters of given types and return void or
references or objects of a given type, _dcl.fct_;
--pointers to void or objects or functions (including static members
of classes) of a given type, _dcl.ptr_;
--references to objects or functions of a given type, _dcl.ref_;
--constants, which are values of a given type, _dcl.type_;
--classes containing a sequence of objects of various types (_class_),
a set of functions for manipulating these objects (_class.mfct_),
and a set of restrictions on the access to these objects and func
tions, _class.access_;
--unions, which are classes capable of containing objects of different
types at different times, _class.union_;
--enumerations, which comprise a set of named constant values. Each
distinct enumeration constitutes a different enumerated type,
_dcl.enum_;
--pointers to non-static21) class members, which identify members of a
given type within objects of a given class, _dcl.mptr_.
2 These methods of constructing types can be applied recursively;
restrictions are mentioned in _dcl.ptr_, _dcl.array_, _dcl.fct_, and
_dcl.ref_.
3 A pointer to objects of type T is referred to as a "pointer to T."
[Example: a pointer to an object of type int is referred to as
"pointer to int" and a pointer to an object of class X is called a
"pointer to X." ] Except for pointers to static members, text refer
ring to "pointers" does not apply to pointers to members. Pointers to
incomplete types are allowed although there are restrictions on what
can be done with them (_basic.types_). The value representation of
pointer types is implementation-defined. Pointers to cv-qualified and
cv-unqualified versions (_basic.type.qualifier_) of layout-compatible
types shall have the same value representation and alignment require
ments (_basic.types_).
4 Objects of cv-qualified (_basic.type.qualifier_) or cv-unqualified
type void* (pointer to void), can be used to point to objects of
_________________________
21) Static class members are objects or functions, and pointers to
them are ordinary pointers to objects or functions.
unknown type. A void* shall be able to hold any object pointer. A
cv-qualified or cv-unqualified (_basic.type.qualifier_) void* shall
have the same representation and alignment requirements as a cv-quali
fied or cv-unqualified char*.
3.9.3 CV-qualifiers [basic.type.qualifier]
1 A type mentioned in _basic.fundamental_ and _basic.compound_ is a cv-
unqualified type. Each cv-unqualified fundamental type (_basic.funda
mental_) has three corresponding cv-qualified versions of its type: a
const-qualified version, a volatile-qualified version, and a const-
volatile-qualified version. The term object type (_intro.object_)
includes the cv-qualifiers specified when the object is created. The
presence of a const specifier in a decl-specifier-seq declares an
object of const-qualified object type; such object is called a const
object. The presence of a volatile specifier in a decl-specifier-seq
declares an object of volatile-qualified object type; such object is
called a volatile object. The presence of both cv-qualifiers in a
decl-specifier-seq declares an object of const-volatile-qualified
object type; such object is called a const volatile object. The cv-
qualified or cv-unqualified versions of a type are distinct types;
however, they shall have the same representation and alignment
requirements (_basic.types_).22)
2 A compound type (_basic.compound_) is not cv-qualified by the cv-qual
ifiers (if any) of the types from which it is compounded. Any cv-
qualifiers that appear in an array declaration apply to the array ele
ment type, not the array type (_dcl.array_).
3 Each non-function, non-static, non-mutable member of a const-qualified
class object is const-qualified, each non-function, non-static member
of a volatile-qualified class object is volatile-qualified and simi
larly for members of a const-volatile class. See _dcl.fct_ and
_class.this_ regarding cv-qualified function types.
4 There is a (partial) ordering on cv-qualifiers, so that a type can be
said to be more cv-qualified than another. Table 1 shows the rela
tions that constitute this ordering.
_________________________
22) The same representation and alignment requirements are meant to
imply interchangeability as arguments to functions, return values from
functions, and members of unions.
Table 1--relations on const and volatile
+----------+
no cv-qualifier<const
no cv-qualifier<volatile
no cv-qualifier<const volatile
const<const volatile
volatile<const volatile
+----------+
5 In this International Standard, the notation cv (or cv1, cv2, etc.),
used in the description of types, represents an arbitrary set of cv-
qualifiers, i.e., one of {const}, {volatile}, {const, volatile}, or
the empty set. Cv-qualifiers applied to an array type attach to the
underlying element type, so the notation "cv T," where T is an array
type, refers to an array whose elements are so-qualified. Such array
types can be said to be more (or less) cv-qualified than other types
based on the cv-qualification of the underlying element types.
3.10 Lvalues and rvalues [basic.lval]
1 Every expression is either an lvalue or an rvalue.
2 An lvalue refers to an object or function. Some rvalue expressions--
those of class or cv-qualified class type--also refer to objects.23)
3 [Note: some built-in operators and function calls yield lvalues.
[Example: if E is an expression of pointer type, then *E is an lvalue
expression referring to the object or function to which E points. As
another example, the function
int& f();
yields an lvalue, so the call f() is an lvalue expression. ] ]
4 [Note: some built-in operators expect lvalue operands. [Example:
built-in assignment operators all expect their left hand operands to
be lvalues. ] Other built-in operators yield rvalues, and some expect
them. [Example: the unary and binary + operators expect rvalue argu
ments and yield rvalue results. ] The discussion of each built-in
operator in clause _expr_ indicates whether it expects lvalue operands
and whether it yields an lvalue. ]
5 Constructor invocations and calls to functions that do not return ref
erences are always rvalues. User defined operators are functions, and
whether such operators expect or yield lvalues is determined by their
type.
_________________________
23) Expressions such as invocations of constructors and of functions
that return a class type refer to objects, and the implementation can
invoke a member function upon such objects, but the expressions are
not lvalues.
6 Whenever an lvalue appears in a context where an rvalue is expected,
the lvalue is converted to an rvalue; see _conv.lval_, _conv.array_,
and _conv.func_.
7 The discussion of reference initialization in _dcl.init.ref_ and of
temporaries in _class.temporary_ indicates the behavior of lvalues and
rvalues in other significant contexts.
8 Class rvalues can have cv-qualified types; non-class rvalues always
have cv-unqualified types. Rvalues shall always have complete types
or the void type; in addition to these types, lvalues can also have
incomplete types.
9 An lvalue for an object is necessary in order to modify the object
except that an rvalue of class type can also be used to modify its
referent under certain circumstances. [Example: a member function
called for an object (_class.mfct_) can modify the object. ]
10Functions cannot be modified, but pointers to functions can be modifi
able.
11A pointer to an incomplete type can be modifiable. At some point in
the program when the pointed to type is complete, the object at which
the pointer points can also be modified.
12The referent of a const-qualified expression shall not be modified
(through that expression), except that if it is of class type and has
a mutable component, that component can be modified (_dcl.type.cv_).
13If an expression can be used to modify the object to which it refers,
the expression is called modifiable. A program that attempts to mod
ify an object through a nonmodifiable lvalue or rvalue expression is
ill-formed.
14If a program attempts to access the stored value of an object through
an lvalue of other than one of the following types the behavior is
undefined24):
--the dynamic type of the object,
--a cv-qualified version of the dynamic type of the object,
--a type that is the signed or unsigned type corresponding to the
dynamic type of the object,
--a type that is the signed or unsigned type corresponding to a cv-
qualified version of the dynamic type of the object,
--an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
_________________________
24) The intent of this list is to specify those circumstances in which
an object may or may not be aliased.
subaggregate or contained union),
--a type that is a (possibly cv-qualified) base class type of the
dynamic type of the object,
--a char or unsigned char type.