______________________________________________________________________
3 Basic concepts [basic]
______________________________________________________________________
1 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, set of functions, 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_).
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_). Every name
is introduced in some contiguous portion of program text called a
declarative region (_basic.scope_), which is the largest part of the
program in which that name can possibly be valid. In general, each
particular name is valid only within some possibly discontiguous por
tion of program text called its scope (_basic.scope_). To determine
the scope of a declaration, it is sometimes convenient to refer to the
potential scope of a declaration. The scope of a declaration is the
same as its potential scope unless the potential scope contains
another declaration of the same name. In that case, the potential
scope of the declaration in the inner (contained) declarative region
is excluded from the scope of the declaration in the outer (contain
ing) declarative region.
6 For example, in
int j = 24;
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.
7 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.
8 Two names denote the same entity 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.
9 An identifier used in more than one translation unit may potentially
refer to the same entity in these translation units depending on the
linkage (_basic.link_) specified in the translation units.
10An object is a region of storage (_basic.lval_). In addition to giv
ing it a name, declaring an object gives the object a storage dura
tion, (_basic.stc_), which determines the object's lifetime. Some
objects are polymorphic; the implementation generates information car
ried in each such object that makes it possible to determine that
object's type during program execution. For other objects, the mean
ing of the values found therein is determined by the type of the
expressions used to access them.
+------- BEGIN BOX 1 -------+
Most of this section needs more work.
+------- END BOX 1 -------+
3.1 Declarations and definitions [basic.def]
1 A declaration (_dcl.dcl_) introduces one or more names into a program
and gives each name a meaning.
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 declara
tion(_namespace.udecl_), or a using directive(_namespace.udir_).
3 The following, for example, are definitions:
int a; // defines a
extern const int c = 1; // defines c
int f(int x) { return x+a; } // defines f
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
4 In some circumstances, C++ implementations generate definitions auto
matically. These definitions include default constructors, copy con
structors, assignment operators, and destructors. For example, given
struct C {
string s; // string is the standard library class (_lib.string_)
};
main()
{
C a;
C b=a;
b=a;
}
the implementation will generate 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() { }
};
5 A class name can also implicitly be declared by an elaborated-type-
specifier (_dcl.type.elab_).
3.2 One definition rule [basic.def.odr]
+------- BEGIN BOX 2 -------+
This is still very much under review by the Committee.
+------- END BOX 2 -------+
1 No translation unit shall contain more than one definition of any
variable, function, class type, enumeration type or template.
2 A function is used if it is called, its address is taken, or it is a
virtual member function that is not pure (_class.abstract_). Every
program shall contain at least one definition of every function that
is used in that program. That definition may appear explicitly in the
program, it may be found in the standard or a user-defined library, or
(when appropriate) the implementation may generate it. If a non-
virtual function is not defined, a diagnostic is required only if an
attempt is actually made to call that function. If a virtual function
is neither called nor defined, no diagnostic is required.
+------- BEGIN BOX 3 -------+
This says nothing about user-defined libraries. Probably it
shouldn't, but perhaps it should be more explicit that it isn't dis
cussing it.
+------- END BOX 3 -------+
3 Exactly one definition in a program is required for a non-local vari
able with static storage duration, unless it has a builtin type or is
an aggregate and also is unused or used only as the operand of the
sizeof operator.
+------- BEGIN BOX 4 -------+
This is still uncertain.
+------- END BOX 4 -------+
4 At least one definition of a class is required in a translation unit
if the class is used other than in the formation of a pointer or ref
erence type.
+------- BEGIN BOX 5 -------+
This is not quite right, because it is possible to declare a function
that has an undefined class type as its return type, that has argu
ments of undefined class type.
+------- END BOX 5 -------+
+------- BEGIN BOX 6 -------+
There may be other situations that do not require a class to be
defined: extern declarations (i.e. "extern X x;"), declaration of
static members, others???
+------- END BOX 6 -------+
For example the following complete translation unit is well-formed,
even though it never defines X:
struct X; // declare X is a struct type
struct X* x1; // use X in pointer formation
X* x2; // use X in pointer formation
5 There may be more than one definition of a named enumeration type in a
program provided that each definition appears in a different transla
tion unit and the names and values of the enumerators are the same.
+------- BEGIN BOX 7 -------+
This will need to be revisited when the ODR is made more precise
+------- END BOX 7 -------+
6 There may be more than one definition of a class type in a program
provided that each definition appears in a different translation unit
and the definitions describe the same type.
7 No diagnostic is required for a violation of the ODR rule.
+------- BEGIN BOX 8 -------+
This will need to be revisited when the ODR is made more precise
+------- END BOX 8 -------+
3.3 Declarative regions and scopes [basic.scope]
1 The scope rules are summarized in _class.scope_.
3.3.1 Local scope [basic.scope.local]
1 A name declared in a block (_stmt.block_) is local to that block. Its
scope begins at its point of declaration (_basic.scope.pdecl_) and
ends at the end of its declarative region.
2 Names of parameters of a function are local to the function and shall
not be redeclared in the outermost block of that function.
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, condition, and controlling
expression parts of if, while, for, and switch statments are local to
the if, while, for, or switch statement (including the controlled
statement), and shall not be redeclared in a subsequent condition or
controlling expression of that statement nor in the outermost block of
the controlled statement.
5 Names declared in the outermost block of the controlled statement of a
do statement shall not be redeclared in the controlling expression.
3.3.2 Function prototype scope [basic.scope.proto]
1 In a function declaration, or in any function declarator except the
declarator of a function definition, names of parameters (if supplied)
have function prototype scope, which terminates at the end of the
function declarator.
3.3.3 Function scope
1 Labels (_stmt.label_) can be used anywhere in the function in which
they are declared. Only labels have function scope.
3.3.4 Namespace scope [basic.scope.namespace]
1 A name declared in a named or unnamed namespace (_basic.namespace_)
has namespace 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. A namespace member can also be used after
the :: scope resolution operator (_expr.prim_) applied to the name of
its namespace.
2 A name declared outside all named or unnamed namespaces
(_basic.namespace_), blocks (_stmt.block_) and classes (_class_) has
global namespace 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.5 Class scope [basic.scope.class]
1 The name of a class member is local to its class and can be used only
in:
--the scope of that class (_class.scope0_) or a class derived
(_class.derived_) from that 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_).
2 The scope of names introduced by friend declarations is described in
_namespace.def_.
3 The scope rules for classes are summarized in _class.scope0_.
3.3.6 Name hiding [basic.scope.hiding]
1 A name may be hidden by an explicit declaration of that same name in a
nested declarative region or derived class.
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 If a name is in scope and is not hidden it is said to be visible.
4 The region in which a name is visible is called the reach of the name.
+------- BEGIN BOX 9 -------+
The term 'reach' is defined here but never used. More work is needed
with the "descriptive terminology".
+------- END BOX 9 -------+
3.3.7 Explicit qualification [basic.scope.exqual]
+------- BEGIN BOX 10 -------+
The information in this section is very similar to the one provided in
_namespace.qual_. The information in these two sections
(_basic.scope.exqual_ and _namespace.qual_) should be consolidated in
one place.
+------- END BOX 10 -------+
1 A name hidden by a nested declarative region or derived class can
still be used when it is qualified by its class or namespace name
using the :: operator (_expr.prim_, _class.static_, _class.derived_).
A hidden file scope name can still be used when it is qualified by the
unary :: operator (_expr.prim_).
3.3.8 Elaborated type specifier [basic.scope.elab]
1 A class name or enumeration name can be hidden by the name of an
object, function, or enumerator in local, class or namespace scope. A
hidden class name can still be used when appropriately prefixed with
class, struct, or union (_dcl.type_), or when followed by the :: oper
ator. A hidden enumeration name can still be used when appropriately
prefixed with enum (_dcl.type_). For example:
class A {
public:
static int n;
};
main()
{
int A;
A::n = 42; // OK
class A a; // OK
A b; // ill-formed: A does not name a type
}
The scope of class names first introduced in elaborated-type-
specifiers is described in (_dcl.type.elab_).
3.3.9 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. For example,
int x = 12;
{ int x = x; }
2 Here the second x is initialized with its own (unspecified) value.
3 For the point of declaration for an enumerator, see _dcl.enum_.
4 The point of declaration of a function with the extern or friend spec
ifier is in the innermost enclosing namespace just after outermost
nested scope containing it which is contained in the namespace.
+------- BEGIN BOX 11 -------+
The terms "just after the outermost nested scope" imply name injec
tion. We avoided introducing the concept of name injection in the
working paper up until now. We should probably continue to do with
out.
+------- END BOX 11 -------+
5 The point of declaration of a class first declared in an elaborated-
type-specifier is immediately after the identifier;
6 A nonlocal name remains visible up to the point of declaration of the
local name that hides it. For example,
const int i = 2;
{ int i[i]; }
declares a local array of two integers.
7 The point of instantiation of a template is described in _temp.inst_.
3.4 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 may denote the same object,
function, type, template, or value as a name introduced by a declara
tion in another scope:
--When a name has external linkage, the entity it denotes may 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 may be
referred to by names from other scopes of 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 of namespace scope (_basic.scope.namespace_) has internal link
age if it is the name of
--a variable that is explicitly declared static or is explicitly
declared const and neither explicitly declared extern nor previously
declared to have external linkage; or
--a function that is explicitly declared static or is explicitly
declared inline and neither explicitly declared extern nor previ
ously declared to have external linkage; or
--the name of a data member of an anonymous union.
4 A name of namespace scope has external linkage if it is the name of
--a variable, unless it has internal linkage; or
--a function, unless it has internal linkage; or
--a class (_class_) or enumeration (_dcl.enum_) or an enumerator; or
--a template (_temp_).
In addition, a name of class scope has external linkage if the name
of the class has external linkage.
+------- BEGIN BOX 12 -------+
What is the linkage of unnamed classes and their members? Unnamed
enumeration and their enumerators?
+------- END BOX 12 -------+
5 The name of a function declared in a block scope or a variable
declared extern in a block scope has linkage, either internal or
external to match the linkage of prior visible declarations of the
name in the same translation unit, but if there is no prior visible
declaration it has external linkage.
6 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_)) may not be
used to declare an entity with linkage. For example:
void f()
{
struct A { int x; }; // no linkage
extern A a; // ill-formed
}
This implies that names with no linkage cannot be used as template
arguments (_temp.arg_).
7 Two names that are the same and that are declared in different scopes
shall denote the same object, function, type, enumerator, or template
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 or function templates, the func
tion types are identical for purposes of overloading.
8 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 must be identical, except that
such types may differ by the presence or absence of a major array
bound (_dcl.array_). A violation of this rule does not require a diag
nostic.
+------- BEGIN BOX 13 -------+
This needs to specified more precisely to deal with function name
overloading.
+------- END BOX 13 -------+
9 Linkage to non-C++ declarations can be achieved using a linkage-
specification (_dcl.link_).
3.5 Start and termination [basic.start]
3.5.1 Main function [basic.start.main]
1 A program shall contain global a function called main, which is the
designated start of the program.
2 This function is not predefined by the compiler, it cannot be over
loaded, and its type is implementation dependent. The two examples
below are allowed on any implementation. It is recommended that any
further (optional) parameters be added after argv. The function
main() may be defined as
int main() { /* ... */ }
or
int main(int argc, char* argv[]) { /* ... */ }
In the latter form argc shall be the number of arguments passed to the
program from an 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 zero-terminated
strings; and argv[0] shall be the pointer to the initial character of
a zero-terminated string that represents the name used to invoke the
program or "". It is guaranteed that argv[argc]==0.
3 The function main() shall not be called from within a program. The
linkage (_basic.link_) of main() is implementation dependent. The
address of main() shall not be taken and main() shall not be declared
inline or static. The name main is not otherwise reserved. For exam
ple, member functions, classes, and enumerations can be called main,
as may entities in other namespaces.
4 Calling the function
void exit(int);
declared in <cstdlib> (_lib.exit_) terminates the program without
leaving the current block and hence without destroying any local vari
ables (_class.dtor_). The argument value is returned to the program's
environment as the value of the program.
5 A return statement in main() has the effect of leaving the main func
tion (destroying any local variables) 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 execut
ing
return 0;
3.5.2 Initialization of non-local objects [basic.start.init]
+------- BEGIN BOX 14 -------+
This is still under active discussion by the committee.
+------- END BOX 14 -------+
1 The initialization of nonlocal static objects (_basic.stc_) in a
translation unit is done before the first use of any function or
object defined in that translation unit. Such initializations
(_dcl.init_, _class.static_, _class.ctor_, _class.expl.init_) may be
done before the first statement of main() or deferred to any point in
time before the first use of a function or object defined in that
translation unit. The default initialization of all static objects to
zero (_dcl.init_) is performed before any other initialization.
Static objects initialized with constant expressions (_expr.const_)
are initialized before any dynamic (that is, run-time) initialization
takes place. No further order is imposed on the initialization of
objects from different translation units. The initialization of local
static objects is described in _stmt.dcl_.
2 If construction or destruction of a non-local static object ends in
throwing an uncaught exception, the result is to call terminate()
(_except.terminate_).
3.5.3 Termination [basic.start.term]
1 Destructors (_class.dtor_) for initialized static objects are called
when returning from main() and when calling exit() (_lib.exit_).
Destruction is done in reverse order of initialization. The function
atexit() from <cstdlib> can be used to specify that a function must be
called at exit. If atexit() is to be called, objects initialized
before an atexit() call may not be destroyed until after the function
specified in the atexit() call has been called.
2 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.
3 Calling the function
void abort();
declared in <cstdlib> terminates the program without executing
destructors for static objects and without calling the functions
passed to atexit().
3.6 Storage duration [basic.stc]
1 The storage duration of an object determines its lifetime.
2 The storage class specifiers static, auto, and mutable are related to
storage duration as described below.
3.6.1 Static storage duration [basic.stc.static]
1 All non-local variables have static storage duration; such variables
are created and destroyed as described in _basic.start_ and
_stmt.dcl_.
2 Note that 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.
+------- BEGIN BOX 15 -------+
This awaits committee action on the ``as-if'' rule.
+------- END BOX 15 -------+
3 The keyword static may be used to declare a local variable with static
storage duration; for a description of initialization and destruction
of local variables, see _stmt.dcl_.
4 The keyword static applied to a class variable in a class definition
also determines that it has static storage duration.
3.6.2 Automatic storage duration [basic.stc.auto]
1 Local objects not declared static or explicitly declared auto or reg
ister have automatic storage duration and are associated with an invo
cation of a block (_dcl.stc_).
2 Each object with automatic storage duration is initialized
(_dcl.init_) each time the control flow reaches its definition and
destroyed (_class.dtor_) whenever control passes from within the scope
of the object to outside that scope (_stmt.jump_).
3 A named automatic object with a constructor or destructor with side
effects may not be destroyed before the end of its block, nor may it
be eliminated even if it appears to be unused.
3.6.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 (_lib.op.new_) and operator new[]
(_lib.op.new.array_), and the global deallocation functions operator
delete (_lib.op.delete_) and operator delete[]
(_lib.op.delete.array_).
2 These functions are always implicitly declared. The library provides
default definitions for them (_lib.header.new_). A C++ program may
provide at most one definition of any of the functions ::operator
new(size_t), ::operator new[](size_t), ::operator delete(void*),
and/or ::operator delete[](void*). Any such function definitions
replace the default versions. This replacement is global and takes
effect upon program startup (_basic.start_). Allocation and/or deal
location functions may 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.6.3.1 Allocation functions [basic.stc.dynamic.allocation]
1 Allocation functions can be static class member functions or global
functions. They may be overloaded, but the return type shall always
be void* and the first parameter type shall always be size_t
(_expr.sizeof_), an implementation-defined integral type defined in
the standard header <cstddef> (_lib.language.support_).
2 The function shall return the address of a block of available storage
at least as large as the requested size. The order, contiguity, and
initial value of storage allocated by successive calls to an alloca
tion function is unspecified. The pointer returned is suitably
aligned so that it may be assigned to a pointer of any type and then
used to access such an object or an array of such objects in the stor
age allocated (until the storage is explicitly deallocated by a call
to a corresponding deallocation function). Each such allocation shall
yield a pointer to storage (_intro.memory_) disjoint from any other
currently allocated storage. The pointer returned points to the start
(lowest byte address) of the allocated storage. If the size of the
space requested is zero, the value returned shall be nonzero and shall
not pointer to or within any other currently allocated storage. The
results of dereferencing a pointer returned as a request for zero size
are undefined.1)
3 If an allocation function is unable to obtain an appropriate block of
storage, it may invoke the currently installed new_handler2) and/or
throw an exception (_except_) of class alloc (_lib.alloc_) or a class
derived from alloc.
4 If the allocation function returns the null pointer the result is
implementation defined.
3.6.3.2 Deallocation functions [basic.stc.dynamic.deallocation]
1 Like allocation functions, deallocation functions may be static class
member functions or global functions.
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 may be added but deallocation functions may
not be overloaded.
3 The value of the first parameter supplied to a deallocation function
shall be zero, 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 null, 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 A deallocation function may free the storage referenced by the pointer
given as its argument and renders the pointer invalid. The storage
may be available for further allocation. An invalid pointer contains
an unusable value: it cannot even be used in an expression.
_________________________
1) 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.
2) A program-supplied allocation function may obtain the address of
the currently installed new_handler using the set_new_handler() func
tion (_lib.set.new.handler_).
5 If the argument is non-null, the value of a pointer that refers to
deallocated space is indeterminate. The effect of dereferencing an
indeterminate pointer value is undefined.3)
3.6.4 Duration of sub-objects [basic.stc.inherit]
1 The storage duration of class subobjects, base class subobjects and
array elements is that of their complete object (_intro.memory_).
3.6.5 The mutable keyword [basic.stc.mutable]
1 The keyword mutable is grammatically a storage class specifier but is
unrelated to the storage duration (lifetime) of the class member it
describes. The mutable keyword is described in _basic.lval_,
_expr.ref_, _dcl.stc_ and _dcl.type.cv_.
3.6.6 Reference duration [basic.stc.ref]
1 A reference can be used to name an existing object denoted by an
lvalue. A reference initialization can also create and name a new
object from an lvalue (_dcl.init.ref_).
2 The reference has static storage duration if it is declared non-
locally, automatic storage duration if declared locally including as a
function parameter, or the storage duration of its class if declared
in a class.
3 References may or may not require storage.
4 The duration of a reference is distinct from the duration of the
object it refers to except in the case of a reference declaration ini
tialized by an rvalue (_dcl.init.ref_).
5 The lifetime of a reference bound in a reference initialization
(_dcl.init.ref_) ends on exit from the scope in which the declaration
occurs.
6 The lifetime of a reference bound in a ctor-initializer
(_class.base.init_) is the lifetime of the subobject initialized.
7 The lifetime of a reference bound for a reference parameter in a func
tion call (_expr.call_) is until the completion of the call.
8 Access through a reference to an object which no longer exists or has
not yet been constructed yields undefined behaviour.
+------- BEGIN BOX 16 -------+
Can references be declared auto or static? This section probably does
not belong here.
+------- END BOX 16 -------+
_________________________
3) On some architectures, it causes a system-generated runtime fault.
3.7 Types [basic.types]
+------- BEGIN BOX 17 -------+
Section _class.mem_ describes the concept of layout-compatible types.
Shouldn't this information be described here?
+------- END BOX 17 -------+
1 There are two kinds of types: fundamental types and compound types.
Types may describe objects, references (_dcl.ref_), or functions
(_dcl.fct_).
2 Arrays of unknown size and classes that have been declared but not
defined are called incomplete types because the size and structure of
an instance of the type is unknown. Also, the void type represents an
empty set of values, so that no objects of type void ever exist; void
is an incomplete type. The term incompletely-defined object type is a
synonym for incomplete type; the term completely-defined object type
is a synonym for complete type;
3 A class type (such as class X) may 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 may 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. However, the type of a pointer to array of
unknown size, or of a type defined by a typedef declaration to be an
array of unknown size, cannot be completed.
4 Expressions that have incomplete type are prohibited in some contexts.
For 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
}
3.7.1 Fundamental types [basic.fundamental]
1 There are several fundamental types. The standard header <climits>
specifies the largest and smallest values of each for an implementa
tion.
2 Objects declared as characters char) are large enough to store any
member of the implementation's basic character set. If a character
from this set is stored in a character variable, its value is equiva
lent to the integer code of that character. It is implementation-
specified whether a char object can take on negative values. Charac
ters may 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.
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.
3 An enumeration comprises a set of named integer constant values, which
form the basis for an integral subrange that includes those values.
Each distinct enumeration constitutes a different enumerated type.
Each constant has the type of its enumeration.
4 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, but the implementation may other
wise make any of them equal in storage size. Plain ints have the nat
ural size suggested by the machine architecture; the other signed
integer types are provided to meet special needs.
5 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
(_intro.memory_) as the corresponding signed integer type.4) An align
ment requirement is an implementation-dependent restriction on the
value of a pointer to an object of a given type (_expr.cast_,
_intro.memory_).
6 Unsigned integers, declared unsigned, obey the laws of arithmetic mod
ulo 2n where n is the number of bits in the representation of that
particular size of integer. This implies that unsigned arithmetic
does not overflow.
7 Type wchar_t is a distinct type whose values can represent distinct
codes for all members of the largest extended character set specified
among the supported locales (_lib.locale_). Type wchar_t has the same
size, signedness, and alignment requirements (_intro.memory_) as one
of the other integral types, called its underlying type.
_________________________
4) See _dcl.type.simple_ regarding the correspondence between types
and the sequences of type-specifiers that designate them.
8 Values of type bool can be either true or false.5) There are no
signed, unsigned, short, or long bool types or values. As described
below, bool values behave as integral types. Thus, for example, they
participate in integral promotions (_conv.prom_, _expr.type.conv_).
Although values of type bool generally behave as signed integers, for
example by promoting (_conv.prom_) to int instead of unsigned int, a
bool value can successfully be stored in a bit-field of any (nonzero)
size.
9 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. Each
implementation defines the characteristics of the fundamental floating
point types in the standard header <cfloat>.
10Types bool, char, wchar_t, and the signed and unsigned integer types
are collectively called integral types. A synonym for integral type
is integer type. Enumerations (_dcl.enum_) are not integral, but they
can be promoted (_conv.prom_) to int, unsigned int, long, or unsigned
long. Integral and floating types are collectively called arithmetic
types.
11The void type specifies an empty set of values. It is used as the
return type for functions that do not return a value. No object of
type void may be declared. Any expression may be explicitly converted
to type void (_expr.cast_); the resulting expression may 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_).
3.7.2 Compound types [basic.compound]
1 There is a conceptually infinite number of compound types 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 objects
of a given type, _dcl.fct_;
--pointers to 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_),
_________________________
5) Using a bool value in ways described by this International Standard
as ``undefined,'' such as by examining the value of an uninitialized
automatic variable, might cause it to behave as if is neither true nor
false.
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_;
--structures, which are classes without default access restrictions,
_class.access_;
--unions, which are classes capable of containing objects of different
types at different times, _class.union_;
--pointers to non-static6) class members, which identify members of a
given type within objects of a given class, _dcl.mptr_.
2 In general, these methods of constructing types can be applied recur
sively; restrictions are mentioned in _dcl.ptr_, _dcl.array_,
_dcl.fct_, and _dcl.ref_.
3 Any type so far mentioned is an unqualified type. Each unqualified
type has three corresponding qualified versions of its type:7) a
const-qualified version, a volatile-qualified version, and a const-
volatile-qualified version (see _dcl.type_). The cv-qualified or
unqualified versions of a type are distinct types that belong to the
same category and have the same representation and alignment
requirements.8) A compound type is not cv-qualified
(_basic.type.qualifier_) by the cv-qualifiers (if any) of the type
from which it is compounded. However, an array type is considered to
be cv-qualified by the cv-qualifiers of its element type. Moreover,
when an array type is cv-qualified, its element type is considered to
have the same cv-qualifiers.
4 A pointer to objects of a type T is referred to as a pointer to T.
For 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. Pointers to incomplete types are allowed although there
are restrictions on what can be done with them (_basic.types_).
5 Objects of cv-qualified (_basic.type.qualifier_) or unqualified type
void* (pointer to void), can be used to point to objects of unknown
type. A void* must have enough bits to hold any object pointer.
6 Except for pointers to static members, text referring to pointers does
not apply to pointers to members.
_________________________
6) Static class members are objects or functions, and pointers to them
are ordinary pointers to objects or functions.
7) See _dcl.array_ and _dcl.fct_ regarding cv-qualified array and
function types.
8) The same representation and alignment requirements are meant to im
ply interchangeability as arguments to functions, return values from
functions, and members of unions.
3.7.3 CV-qualifiers [basic.type.qualifier]
+------- BEGIN BOX 18 -------+
This section covers the same information as section _dcl.type.cv_.
This information should probably be consolidated in one place.
+------- END BOX 18 -------+
1 There are two cv-qualifiers, const and volatile. When applied to an
object, const means the program may not change the object, and
volatile has an implementation-defined meaning.9) An object may have
both cv-qualifiers.
2 There is a (partial) ordering on cv-qualifiers, so that one object or
pointer may be said to be more cv-qualified than another. Table 1
shows the relations that constitute this ordering.
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 |
+-------------------------------------+
3 A pointer or reference to cv-qualified type (sometimes called a cv-
qualified pointer or reference) need not actually point to a cv-
qualified object, but it is treated as if it does. For example, a
pointer to const int may point to an unqualified int, but a well-
formed program may not attempt to change the pointed-to object through
that pointer even though it may change the same object through some
other access path. CV-qualifiers are supported by the type system so
that a cv-qualified object or cv-qualified access path to an object
may not be subverted without casting (_expr.cast_). For example:
_________________________
9) Roughly, volatile means the object may change of its own accord
(that is, the processor may not assume that the object continues to
hold a previously held value).
void f()
{
int i = 2; // not cv-qualified
const int ci = 3; // cv-qualified (initialized as required)
ci = 4; // error: attempt to modify const
const int* cip; // pointer to const int
cip = &i; // okay: cv-qualified access path to unqualified
*cip = 4; // error: attempt to modify through ptr to const
int* ip;
ip = cip; // error: attempt to convert const int* to int*
}
4 In this document, 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 ele
ment 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.7.4 Type names [basic.type.name]
1 Fundamental and compound types can be given names by the typedef mech
anism (_dcl.typedef_), and families of types and functions can be
specified and named by the template mechanism (_temp_).
3.8 Lvalues and rvalues [basic.lval]
1 Every expression is either an lvalue or 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.10)
3 Some builtin operators and function calls yield lvalues. For 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 Some builtin operators expect lvalue operands, for example the builtin
assignment operators all expect their left hand operands to be lval
ues. Other builtin operators yield rvalues, and some expect them.
For example the unary and binary + operator expect rvalue arguments
and yield rvalue results. The discussion of each builtin operator in
_expr_ indicates whether it expects lvalue operands and whether it
yields an lvalue.
_________________________
10) Expressions such as invocations of constructors and of functions
that return a class type do in some sense refer to an object, and the
implementation may invoke a member function upon such objects, but the
expressions are not lvalues.
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.
6 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.
7 Class rvalues may have qualified types; non-class rvalues always have
unqualified types.
8 Whenever an lvalue appears in a context where an lvalue is not
expected, the lvalue is converted to an rvalue; see _conv.lval_,
_conv.array_, and _conv.func_.
9 An lvalue or rvalue of class type can also be used to modify its ref
erent under certain circumstances.
+------- BEGIN BOX 19 -------+
Provide example and cross-reference.
+------- END BOX 19 -------+
10Functions cannot be modified, but pointers to functions may be modifi
able.
11A pointer to an incomplete type may be modifiable. At some point in
the program when this pointer type is complete, the object at which
the pointer points may also be modified.
12Array objects cannot be modified, but their elements may be modifi
able.
13The 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 may be modified.
14If an expression can be used to modify its object, it is called modi
fiable. A program that attempts to modify an object through a nonmod
ifiable lvalue or rvalue expression is ill-formed.