______________________________________________________________________
7 Declarations [dcl.dcl]
______________________________________________________________________
1 A declaration introduces one or more names into a program and speci
fies how those names are to be interpreted. Declarations have the
form
declaration-seq:
declaration
declaration-seq declaration
declaration:
block-declaration
function-definition
template-declaration
linkage-specification
namespace-definition
block-declaration:
simple-declaration
asm-definition
namespace-alias-definition
using-declaration
using-directive
simple-declaration:
decl-specifier-seqopt init-declarator-listopt ;
[Note: asm-definitions are described in _dcl.asm_, and linkage-
specifications are described in _dcl.link_. Function-definitions are
described in _dcl.fct.def_ and template-declarations are described in
_temp_. Namespace-definitions are described in _namespace.def_,
using-declarations are described in _namespace.udecl_ and using-
directives are described in _namespace.udir_. ] The simple-
declaration
decl-specifier-seqopt init-declarator-listopt ;
is divided into two parts: decl-specifiers, the components of a decl-
specifier-seq, are described in _dcl.spec_ and declarators, the compo
nents of an init-declarator-list, are described in _dcl.decl_.
2 A declaration occurs in a scope (_basic.scope_); the scope rules are
summarized in _basic.lookup_. A declaration that declares a function
or defines a class, namespace, template, or function also has one or
more scopes nested within it. These nested scopes, in turn, can have
declarations nested within them. Unless otherwise stated, utterances
in this clause about components in, of, or contained by a declaration
or subcomponent thereof refer only to those components of the declara
tion that are not nested within scopes nested within the declaration.
3 In a simple-declaration, the optional init-declarator-list can be
omitted only when declaring a class (_class_) or enumeration
(_dcl.enum_), that is, when the decl-specifier-seq contains either a
class-specifier, an elaborated-type-specifier with a class-key
(_class.name_), or an enum-specifier. In these cases and whenever a
class-specifier or enum-specifier is present in the decl-specifier-
seq, the identifiers in these specifiers are among the names being
declared by the declaration (as class-names, enum-names, or enumera
tors, depending on the syntax).
4 Each init-declarator in the init-declarator-list contains exactly one
declarator-id, which is the name declared by that init-declarator and
hence one of the names declared by the declaration. The type-
specifiers (_dcl.type_) in the decl-specifier-seq and the recursive
declarator structure of the init-declarator describe a type
(_dcl.meaning_), which is then associated with the name being declared
by the init-declarator.
5 If the decl-specifier-seq contains the typedef specifier, the declara
tion is called a typedef declaration and the name of each init-
declarator is declared to be a typedef-name, synonymous with its asso
ciated type (_dcl.typedef_). If the decl-specifier-seq contains no
typedef specifier, the declaration is called a function declaration if
the type associated with the name is a function type (_dcl.fct_) and
an object declaration otherwise.
6 Syntactic components beyond those found in the general form of decla
ration are added to a function declaration to make a function-
definition. An object declaration, however, is also a definition
unless it contains the extern specifier and has no initializer
(_basic.def_). A definition causes the appropriate amount of storage
to be reserved and any appropriate initialization (_dcl.init_) to be
done.
7 Only in function declarations for constructors, destructors, and type
conversions can the decl-specifier-seq be omitted.1)
8 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-
specifier (_basic.scope.pdecl_), and using-directives (_names
pace.udir_) alter this general behavior.
7.1 Specifiers [dcl.spec]
1 The specifiers that can be used in a declaration are
decl-specifier:
storage-class-specifier
type-specifier
function-specifier
friend
typedef
_________________________
The "implicit int" rule of C is no longer supported.
decl-specifier-seq:
decl-specifier-seqopt decl-specifier
2 The longest sequence of decl-specifiers that could possibly be a type
name is taken as the decl-specifier-seq of a declaration. The
sequence shall be self-consistent as described below. [Example:
typedef char* Pc;
static Pc; // error: name missing
Here, the declaration static Pc is ill-formed because no name was
specified for the static variable of type Pc. To get a variable of
type int called Pc, the type-specifier int has to be present to indi
cate that the typedef-name Pc is the name being (re)declared, rather
than being part of the decl-specifier sequence. For another example,
void f(const Pc); // void f(char* const) (not const char*)
void g(const int Pc); // void g(const int)
--end example]
3 [Note: since signed, unsigned, long, and short by default imply int, a
type-name appearing after one of those specifiers is treated as the
name being (re)declared. [Example:
void h(unsigned Pc); // void h(unsigned int)
void k(unsigned int Pc); // void k(unsigned int)
--end example] --end note]
7.1.1 Storage class specifiers [dcl.stc]
1 The storage class specifiers are
storage-class-specifier:
auto
register
static
extern
mutable
At most one storage-class-specifier shall appear in a given decl-
specifier-seq. If a storage-class-specifier appears in a decl-
specifier-seq, there can be no typedef specifier in the same decl-
specifier-seq and the init-declarator-list of the declaration shall
not be empty (except for global anonymous unions, which shall be
declared static (_class.union_). The storage-class-specifier applies
to the name declared by each init-declarator in the list and not to
any names declared by other specifiers.
2 The auto or register specifiers can be applied only to names of
objects declared in a block (_stmt.block_) or to function parameters
(_dcl.fct.def_). They specify that the named object has automatic
storage duration (_basic.stc.auto_). An object declared without a
storage-class-specifier at block scope or declared as a function
parameter has automatic storage duration by default. Hence, the auto
specifier is almost always redundant and not often used; one use of
auto is to distinguish a declaration-statement from an expression-
statement (_stmt.expr_) explicitly.
3 A register specifier has the same semantics as an auto specifier
together with a hint to the implementation that the object so declared
will be heavily used. The hint can be ignored and in most implementa
tions it will be ignored if the address of the object is taken.
4 The static specifier can be applied only to names of objects and func
tions and to anonymous unions (_class.union_). There can be no static
function declarations within a block, nor any static function parame
ters. A static specifier used in the declaration of an object
declares the object to have static storage duration
(_basic.stc.static_). A static specifier can be used in declarations
of class members; _class.static_ describes its effect. For the link
age of a name declared with a static specifier, see _basic.link_. For
a nonmember function, an inline specifier is equivalent to a static
specifier for linkage purposes (_basic.link_) unless the inline decla
ration explicitly includes extern as part of its decl-specifier or
matches a previous declaration of the function, in which case the
function name retains the linkage of the previous declaration.
5 The extern specifier can be applied only to the names of objects and
functions. The extern specifier cannot be used in the declaration of
class members or function parameters. For the linkage of a name
declared with an extern specifier, see _basic.link_.
6 A name declared in a namespace scope without a storage-class-specifier
has external linkage unless it has internal linkage because of a pre
vious declaration and provided it is not declared const. Objects
declared const and not explicitly declared extern have internal link
age.
7 The linkages implied by successive declarations for a given entity
shall agree. That is, within a given scope, each declaration declar
ing the same object name or the same overloading of a function name
shall imply the same linkage. Each function in a given set of over
loaded functions can have a different linkage, however. [Example:
static char* f(); // f() has internal linkage
char* f() // f() still has internal linkage
{ /* ... */ }
char* g(); // g() has external linkage
static char* g() // error: inconsistent linkage
{ /* ... */ }
void h();
inline void h(); // external linkage
inline void l();
void l(); // internal linkage
inline void m();
extern void m(); // internal linkage
static void n();
inline void n(); // internal linkage
static int a; // `a' has internal linkage
int a; // error: two definitions
static int b; // `b' has internal linkage
extern int b; // `b' still has internal linkage
int c; // `c' has external linkage
static int c; // error: inconsistent linkage
extern int d; // `d' has external linkage
static int d; // error: inconsistent linkage
--end example]
8 The name of a declared but undefined class can be used in an extern
declaration. Such a declaration, however, cannot be used before the
class has been defined. [Example:
struct S;
extern S a;
extern S f();
extern void g(S);
void h()
{
g(a); // error: S undefined
f(); // error: S undefined
}
--end example] The mutable specifier can be applied only to names of
class data members (_class.mem_) and can not be applied to names
declared const or static. [Example:
class X {
mutable const int* p; // ok
mutable int* const q; // ill-formed
};
--end example]
9 The mutable specifier on a class data member nullifies a const speci
fier applied to the containing class object and permits modification
of the mutable class member even though the rest of the object is
const (_dcl.type.cv_).
7.1.2 Function specifiers [dcl.fct.spec]
1 Function-specifiers can be used only in function declarations.
function-specifier:
inline
virtual
explicit
2 A function declaration (_dcl.fct_, _class.mfct_, _class.friend_) with
an inline specifier declares an inline function. The inline specifier
indicates to the implementation that inline substitution of the func
tion body at the point of call is to be preferred to the usual func
tion call mechanism. An implementation is not required to perform
this inline substitution at the point of call; however, even if this
inline substitution is omitted, the other rules for inline functions
defined by this subclause shall still be respected.
3 A function defined within a class definition is an inline function.
The inline specifier shall not appear on a block scope function decla
ration. For the linkage of inline functions, see _basic.link_ and
_dcl.stc_.
4 An inline function shall be defined in every translation unit in which
it is used (_basic.def.odr_), and shall have exactly the same defini
tion in every case (see one definition rule, _basic.def.odr_). If a
function with external linkage is declared inline in one translation
unit, it shall be declared inline in all translation units in which it
appears.
5 The virtual specifier shall be used only in declarations of nonstatic
class member functions within a class declaration; see
_class.virtual_.
6 The explicit specifier shall be used only in declarations of construc
tors within a class declaration; see _class.conv.ctor_.
7.1.3 The typedef specifier [dcl.typedef]
1 Declarations containing the decl-specifier typedef declare identifiers
that can be used later for naming fundamental (_basic.fundamental_) or
compound (_basic.compound_) types. The typedef specifier shall not be
used in a function-definition (_dcl.fct.def_), and it shall not be
combined in a decl-specifier-seq with any other kind of specifier
except a type-specifier.
typedef-name:
identifier
A name declared with the typedef specifier becomes a typedef-name.
Within the scope of its declaration, a typedef-name is syntactically
equivalent to a keyword and names the type associated with the identi
fier in the way described in _dcl.decl_. A typedef-name is thus a
synonym for another type. A typedef-name does not introduce a new
type the way a class declaration (_class.name_) or enum declaration
does. [Example: after
typedef int MILES, *KLICKSP;
the constructions
MILES distance;
extern KLICKSP metricp;
are all correct declarations; the type of distance is int; that of
metricp is "pointer to int." ]
2 In a given scope, a typedef specifier can be used to redefine the name
of any type declared in that scope to refer to the type to which it
already refers. [Example:
typedef struct s { /* ... */ } s;
typedef int I;
typedef int I;
typedef I I;
--end example]
3 In a given scope, a typedef specifier shall not be used to redefine
the name of any type declared in that scope to refer to a different
type. [Example:
class complex { /* ... */ };
typedef int complex; // error: redefinition
--end example] Similarly, in a given scope, a class or enumeration
shall not be declared with the same name as a typedef-name that is
declared in that scope and refers to a type other than the class or
enumeration itself. [Example:
typedef int complex;
class complex { /* ... */ }; // error: redefinition
--end example]
4 A typedef-name that names a class is a class-name (_class.name_). The
typedef-name shall not be used after a class, struct, or union prefix
and not in the names for constructors and destructors within the class
declaration itself. [Example:
struct S {
S();
~S();
};
typedef struct S T;
S a = T(); // ok
struct T * p; // error
--end example]
5 If the typedef declaration defines an unnamed class (or enum), the
first typedef-name declared by the declaration to be that class type
(or enum type) is used to denote the class type (or enum type) for
linkage purposes only (_basic.link_). [Example:
typedef struct { } *ps, S; // 'S' is the class name for linkage purposes
--end example] If the typedef-name is used where a class-name (or
enum-name) is required, the program is ill-formed. [Example:
typedef struct {
S(); // error: requires a return type since S is
// an ordinary member function, not a constructor
} S;
--end example]
7.1.4 The friend specifier [dcl.friend]
1 The friend specifier is used to specify access to class members; see
_class.friend_.
7.1.5 Type specifiers [dcl.type]
1 The type-specifiers are
type-specifier:
simple-type-specifier
class-specifier
enum-specifier
elaborated-type-specifier
cv-qualifier
As a general rule, at most one type-specifier is allowed in the com
plete decl-specifier-seq of a declaration. The only exceptions to
this rule are the following:
2
--const or volatile can be combined with any other type-specifier.
However, redundant cv-qualifiers are prohibited except when intro
duced through the use of typedefs (_dcl.typedef_) or template type
arguments (_temp.arg_), in which case the redundant cv-qualifiers
are ignored.
--signed or unsigned can be combined with char, long, short, or int.
--short or long can be combined with int.
--long can be combined with double.
3 At least one type-specifier is required in a typedef declaration. At
least one type-specifier is required in a function declaration unless
it declares a constructor, destructor or type conversion operator.1)
4 class-specifiers and enum-specifiers are discussed in _class_ and
_dcl.enum_, respectively. The remaining type-specifiers are discussed
in the rest of this section.
7.1.5.1 The cv-qualifiers [dcl.type.cv]
1 There are two cv-qualifiers, const and volatile. [Note:
_basic.type.qualifier_ describes how cv-qualifiers affect object and
function types. ]
2 Unless explicitly declared extern, an object declared with a const-
qualified type has internal linkage and shall be initialized
(_dcl.init_, _class.ctor_). For an object of const-qualified type T,
if no explicit initializer is specified to initialize the object, and
T is a class with a user-declared default constructor, the constructor
for T is called; otherwise, the program is ill-formed. An integral or
enumeration object of const-qualified type initialized by an integral
or enumeration constant expression can be used in integral or enumera
tion constant expressions (_expr.const_).
3 A pointer or reference to a cv-qualified type need not actually point
or refer to a cv-qualified object, but it is treated as if it does; a
const-qualified access path cannot be used to modify an object even if
the object referenced is a non-const object and can be modified
through some other access path. [Note: cv-qualifiers are supported by
the type system so that they cannot be subverted without casting
(_expr.const.cast_). ]
4 Except that any class member declared mutable (_dcl.stc_) can be modi
fied, any attempt to modify a const object during its lifetime
(_basic.life_) results in undefined behavior.
_________________________
1) There is no special provision for a decl-specifier-seq that lacks a
type-specifier. The "implicit int" rule of C is no longer supported.
5 [Example:
const int ci = 3; // cv-qualified (initialized as required)
ci = 4; // ill-formed: attempt to modify const
int i = 2; // not cv-qualified
const int* cip; // pointer to const int
cip = &i; // okay: cv-qualified access path to unqualified
*cip = 4; // ill-formed: attempt to modify through ptr to const
int* ip;
ip = const_cast<int*> cip; // cast needed to convert const int* to int*
*ip = 4; // defined: *ip points to i, a non-const object
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*> ciq; // cast required
*iq = 4; // undefined: modifies a const object
6 For another example
class X {
public:
mutable int i;
int j;
};
class Y {
public:
X x;
Y();
};
const Y y;
y.x.i++; // well-formed: mutable member can be modified
y.x.j++; // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y); // cast away const-ness of y
p->x.i = 99; // well-formed: mutable member can be modified
p->x.j = 99; // undefined: modifies a const member
--end example]
7 [Note: volatile is a hint to the implementation to avoid aggressive
optimization involving the object because the value of the object
might be changed by means undetectable by an implementation. See
_intro.execution_ for detailed semantics. In general, the semantics
of volatile are intended to be the same in C++ as they are in C. ]
7.1.5.2 Simple type specifiers [dcl.type.simple]
1 The simple type specifiers are
simple-type-specifier:
::opt nested-name-specifieropt type-name
char
wchar_t
bool
short
int
long
signed
unsigned
float
double
void
type-name:
class-name
enum-name
typedef-name
The simple-type-specifiers specify either a previously-declared user-
defined type or one of the fundamental types (_basic.fundamental_).
Table 1 summarizes the valid combinations of simple-type-specifiers
and the types they specify.
Table 1--simple-type-specifiers and the types they specify
+-------------------+----------------------+
|Specifier(s) | Type |
+-------------------+----------------------+
|type-name | the type named |
|char | "char" |
|unsigned char | "unsigned char" |
|signed char | "signed char" |
|bool | "bool" |
|unsigned | "unsigned int" |
|unsigned int | "unsigned int" |
|signed | "int" |
|signed int | "int" |
|int | "int" |
|unsigned short int | "unsigned short int" |
|unsigned short | "unsigned short int" |
|unsigned long int | "unsigned long int" |
|unsigned long | "unsigned long int" |
|signed long int | "long int" |
|signed long | "long int" |
|long int | "long int" |
|long | "long int" |
|signed short int | "short int" |
|signed short | "short int" |
|short int | "short int" |
|short | "short int" |
|wchar_t | "wchar_t" |
|float | "float" |
|double | "double" |
|long double | "long double" |
|void | "void" |
+-------------------+----------------------+
When multiple simple-type-specifiers are allowed, they can be freely
intermixed with other decl-specifiers in any order. It is implementa
tion-defined whether bit-fields and objects of char type are repre
sented as signed or unsigned quantities. The signed specifier forces
char objects and bit-fields to be signed; it is redundant with other
integral types.
7.1.5.3 Elaborated type specifiers [dcl.type.elab]
1 elaborated-type-specifier:
class-key ::opt nested-name-specifieropt identifier
enum ::opt nested-name-specifieropt identifier
class-key:
class
struct
union
2 If an elaborated-type-specifier is the sole constituent of a declara
tion, the declaration is ill-formed unless it has one of the following
forms:
-- class-key identifier ;
3 -- friend class-key identifier ;
4 -- friend class-key ::identifier ;
friend class-key nested-name-specifier identifier ;
5 _basic.lookup.elab_ describes how name look up proceeds for the iden
tifier in an elaborated-type-specifier. If the identifier resolves to
a class-name or enum-name, the elaborated-type-specifier introduces it
into the declaration the same way a simple-type-specifier introduces
its type-name. If the identifier resolves to a typedef-name, the
elaborated-type-specifier is ill-formed. If name look up does not
find a declaration for the name, the elaborated-type-specifier is ill-
formed unless it is of the simple form class-key identifier in which
case the identifier is declared as described in _basic.scope.pdecl_.
6 The class-key or enum keyword present in the elaborated-type-specifier
shall agree in kind with the declaration to which the name in the
elaborated-type-specifier refers. This rule also applies to the form
of elaborated-type-specifier that declares a class-name or friend
class since it can be construed as referring to the definition of the
class. Thus, in any elaborated-type-specifier, the enum keyword shall
be used to refer to an enumeration (_dcl.enum_), the union class-key
shall be used to refer to a union (_class_), and either the class or
struct class-key shall be used to refer to a class (_class_) declared
using the class or struct class-key.
7.2 Enumeration declarations [dcl.enum]
1 An enumeration is a distinct type (_basic.fundamental_) with named
constants. Its name becomes an enum-name, within its scope.
enum-name:
identifier
enum-specifier:
enum identifieropt { enumerator-listopt }
enumerator-list:
enumerator-definition
enumerator-list , enumerator-definition
enumerator-definition:
enumerator
enumerator = constant-expression
enumerator:
identifier
The identifiers in an enumerator-list are declared as constants, and
can appear wherever constants are required. If no enumerator-
definitions with = appear, then the values of the corresponding
constants begin at zero and increase by one as the enumerator-list is
read from left to right. An enumerator-definition with = gives the
associated enumerator the value indicated by the constant-expression;
subsequent enumerators without initializers continue the progression
from the assigned value. The constant-expression shall be of integral
or enumeration type.
2 [Example:
enum { a, b, c=0 };
enum { d, e, f=e+2 };
defines a, c, and d to be zero, b and e to be 1, and f to be 3. ]
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 Each enumeration defines a type that is different from all other
types. The type of an enumerator is its enumeration.
5 The underlying type of an enumeration is an integral type that can
represent all the enumerator values defined in the enumeration. It is
implementation-defined which integral type is used as the underlying
type for an enumeration except that the underlying type shall not be
larger than int unless the value of an enumerator cannot fit in an int
or unsigned int. If the enumerator-list is empty, the underlying type
is as if the enumeration had a single enumerator with value 0. The
value of sizeof() applied to an enumeration type, an object of enumer
ation type, or an enumerator, is the value of sizeof() applied to the
underlying type.
6 For an enumeration where emin is the smallest enumerator and emax is
the largest, the values of the enumeration are the values of the
underlying type in the range bmin to bmax, where bmin and bmax are,
respectively, the smallest and largest values of the smallest bit-
field that can store emin and emax. On a two's-complement machine,
bmax is the smallest value greater than or equal to
max(abs(emin)-1,abs(emax)) of the form 2M-1; bmin is zero if emin is
non-negative and -(bmax+1) otherwise. It is possible to define an
enumeration that has values not defined by any of its enumerators.
7 Two enumeration types are layout-compatible if they have the same
underlying type.
8 The value of an enumerator or an object of an enumeration type is con
verted to an integer by integral promotion (_conv.prom_). [Example:
enum color { red, yellow, green=20, blue };
color col = red;
color* cp = &col;
if (*cp == blue) // ...
makes color a type describing various colors, and then declares col as
an object of that type, and cp as a pointer to an object of that type.
The possible values of an object of type color are red, yellow, green,
blue; these values can be converted to the integral values 0, 1, 20,
and 21. Since enumerations are distinct types, objects of type color
can be assigned only values of type color.
color c = 1; // error: type mismatch,
// no conversion from int to color
int i = yellow; // ok: yellow converted to integral value 1
// integral promotion
See also _diff.anac_. ]
9 An expression of arithmetic or enumeration type can be converted to an
enumeration type explicitly. The value is unchanged if it is in the
range of enumeration values of the enumeration type; otherwise the
resulting enumeration value is unspecified.
10The enum-name and each enumerator declared by an enum-specifier is
declared in the scope that immediately contains the enum-specifier.
These names obey the scope rules defined for all names in
(_basic.scope_) and (_basic.lookup_). An enumerator declared in class
scope can be referred to using the class member access operators ::, .
(dot) and -> (arrow)), see _expr.ref_. [Example:
class X {
public:
enum direction { left='l', right='r' };
int f(int i)
{ return i==left ? 0 : i==right ? 1 : 2; }
};
void g(X* p)
{
direction d; // error: `direction' not in scope
int i;
i = p->f(left); // error: `left' not in scope
i = p->f(X::right); // ok
i = p->f(p->left); // ok
// ...
}
--end example]
7.3 Namespaces [basic.namespace]
1 A namespace is an optionally-named declarative region. The name of a
namespace can be used to access entities declared in that namespace;
that is, the members of the namespace. Unlike other declarative
regions, the definition of a namespace can be split over several parts
of one or more translation units.
2 A name declared outside all named namespaces, blocks (_stmt.block_)
and classes (_class_) has global namespace scope
(_basic.scope.namespace_).
7.3.1 Namespace definition [namespace.def]
1 The grammar for a namespace-definition is
namespace-name:
original-namespace-name
namespace-alias
original-namespace-name:
identifier
namespace-definition:
named-namespace-definition
unnamed-namespace-definition
named-namespace-definition:
original-namespace-definition
extension-namespace-definition
original-namespace-definition:
namespace identifier { namespace-body }
extension-namespace-definition:
namespace original-namespace-name { namespace-body }
unnamed-namespace-definition:
namespace { namespace-body }
namespace-body:
declaration-seqopt
2 The identifier in an original-namespace-definition shall not have been
previously defined in the declarative region in which the original-
namespace-definition appears. The identifier in an original-
namespace-definition is the name of the namespace. Subsequently in
that declarative region, it is treated as an original-namespace-name.
3 The original-namespace-name in an extension-namespace-definition shall
have previously been defined in an original-namespace-definition in
the same declarative region.
4 Every namespace-definition shall appear in the global scope or in a
namespace scope (_basic.scope.namespace_).
5 Because a namespace-definition contains declarations in its namespace-
body and a namespace-definition is itself a declaration, it follows
that namespace-definitions can be nested. [Example:
namespace Outer {
int i;
namespace Inner {
void f() { i++; } // Outer::i
int i;
void g() { i++; } // Inner::i
}
}
--end example]
7.3.1.1 Unnamed namespaces [namespace.unnamed]
1 An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where, for each translation unit, all occurrences of unique in that
translation unit are replaced by an identifier that differs from all
other identifiers in the entire program.2) [Example:
namespace { int i; } // unique::i
void f() { i++; } // unique::i++
namespace A {
namespace {
int i; // A::unique::i
int j; // A::unique::j
}
void g() { i++; } // A::unique::i++
}
using namespace A;
void h() {
i++; // error: unique::i or A::unique::i
A::i++; // A::unique::i
j++; // A::unique::j
}
--end example]
2 The use of the static keyword is deprecated when declaring objects in
a namespace scope (see Annex _depr_); the unnamed-namespace provides a
superior alternative.
7.3.1.2 Namespace member definitions [namespace.memdef]
1 Members of a namespace can be defined within that namespace. [Exam
ple:
namespace X {
void f() { /* ... */ }
}
--end example]
2 Members of a named namespace can also be defined outside that names
pace by explicit qualification (_namespace.qual_) of the name being
defined, provided that the entity being defined was already declared
in the namespace and the definition appears after the point of decla
ration in a namespace that encloses the declaration's namespace.
_________________________
2) Although entities in an unnamed namespace might have external link
age, they are effectively qualified by a name unique to their transla
tion unit and therefore can never be seen from any other translation
unit.
[Example:
namespace Q {
namespace V {
void f();
}
void V::f() { /* ... */ } // fine
void V::g() { /* ... */ } // error: g() is not yet a member of V
namespace V {
void g();
}
}
namespace R {
void Q::V::g() { /* ... */ } // error: R doesn't enclose Q
}
--end example]
3 Every name first declared in a namespace is a member of that names
pace. A friend function first declared within a class is a member of
the innermost enclosing namespace. When looking for a prior declara
tion of a class or a function declared as a friend, scopes outside the
innermost enclosing namespace scope are not considered. [Example:
// Assume f and g have not yet been defined.
friend void h(int);
namespace A {
class X {
friend void f(X); // declaration of f
class Y {
friend void g(); // A::g is a friend
friend void h(int); // A::h is a friend
// ::h not considered
};
};
void f(X) { /* ... */} // definition of f declared above
X x;
void g() { f(x); } // f and g are members of A
void h(int) { /* ... */ } // h is a member of A
}
using A::x;
void h()
{
A::f(x);
A::X::f(x); // error: f is not a member of A::X
A::X::Y::g(); // error: g is not a member of A::X::Y
}
--end example] The scope of class names first introduced in elabo
rated-type-specifiers is described in (_basic.scope.pdecl_).
4 When an entity declared with a block scope extern declaration is not
found to refer to some other declaration, then that entity is a member
of the innermost enclosing namespace. However such a declaration does
not introduce the member name in its namespace scope. [Example:
namespace X {
void p()
{
q(); // error: q not yet declared
extern void q(); // q is a member of namespace X
}
void middle()
{
q(); // error: q not yet declared
}
void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q
--end example]
7.3.2 Namespace alias [namespace.alias]
1 A namespace-alias-definition declares an alternate name for a names
pace according to the following grammar:
namespace-alias:
identifier
namespace-alias-definition:
namespace identifier = qualified-namespace-specifier ;
qualified-namespace-specifier:
::opt nested-name-specifieropt namespace-name
2 The identifier in a namespace-alias-definition is a synonym for the
name of the namespace denoted by the qualified-namespace-specifier and
becomes a namespace-alias. [Note: when looking up a namespace-name is
a namespace-alias-definition, only namespace names are considered, see
_basic.lookup.udir_. ]
3 In a declarative region, a namespace-alias-definition can be used to
redefine a namespace-alias declared in that declarative region to
refer to the namespace to which it already refers. [Example: the fol
lowing declarations are well-formed:
namespace Company_with_very_long_name { /* ... */ }
namespace CWVLN = Company_with_very_long_name;
namespace CWVLN = Company_with_very_long_name; // ok: duplicate
namespace CWVLN = CWVLN;
--end example]
4 A namespace-name or namespace-alias shall not be declared as the name
of any other entity in the same declarative region. A namespace-name
defined at global scope shall not be declared as the name of any other
entity in any global scope of the program. No diagnostic is required
for a violation of this rule by declarations in different translation
units.
7.3.3 The using declaration [namespace.udecl]
1 A using-declaration introduces a name into the declarative region in
which the using-declaration appears. That name is a synonym for the
name of some entity declared elsewhere. A name specified in a using-
declaration in a class or namespace scope shall not already be a mem
ber of that scope.
using-declaration:
using ::opt nested-name-specifier unqualified-id ;
using :: unqualified-id ;
+------- BEGIN BOX 1 -------+
There is still an open issue regarding the "opt" on the nested-name-
specifier.
+------- END BOX 1 -------+
2 The member names specified in a using-declaration are declared in the
declarative region in which the using-declaration appears.
3 Every using-declaration is a declaration and a member-declaration and
so can be used in a class definition. [Example:
struct B {
void f(char);
void g(char);
};
struct D : B {
using B::f;
void f(int) { f('c'); } // calls B::f(char)
void g(int) { g('c'); } // recursively calls D::g(int)
};
--end example]
4 A using-declaration used as a member-declaration shall refer to a mem
ber of a base class of the class being defined. [Example:
class C {
int g();
};
class D2 : public B {
using B::f; // ok: B is a base of D2
using C::g; // error: C isn't a base of D2
};
--end example] [Note: since constructors and destructors do not have
names, a using-declaration cannot refer to a constructor or a destruc
tor for a base class. ]
5 A using-declaration for a member shall be a member-declaration.
[Example:
struct X {
int i;
static int s;
};
void f()
{
using X::i; // error: X::i is a class member
// and this is not a member declaration.
using X::s; // error: X::s is a class member
// and this is not a member declaration.
}
--end example]
6 Members declared by a using-declaration can be referred to by explicit
qualification just like other member names (_namespace.qual_). In a
using-declaration, a prefix :: refers to the global namespace. [Exam
ple:
void f();
namespace A {
void g();
}
namespace X {
using ::f; // global f
using A::g; // A's g
}
void h()
{
X::f(); // calls ::f
X::g(); // calls A::g
}
--end example]
7 A using-declaration is a declaration and can therefore be used repeat
edly where (and only where) multiple declarations are allowed. [Exam
ple:
namespace A {
int i;
}
namespace A1 {
using A::i;
using A::i; // ok: double declaration
}
void f()
{
using A::i;
using A::i; // error: double declaration
}
class B {
public:
int i;
};
class X : public B {
using B::i;
using B::i; // error: double member declaration
};
--end example]
8 The entity declared by a using-declaration shall be known in the con
text using it according to its definition at the point of the using-
declaration. Definitions added to the namespace after the using-
declaration are not considered when a use of the name is made. [Exam
ple:
namespace A {
void f(int);
}
using A::f; // f is a synonym for A::f;
// that is, for A::f(int).
namespace A {
void f(char);
}
void foo()
{
f('a'); // calls f(int),
} // even though f(char) exists.
void bar()
{
using A::f; // f is a synonym for A::f;
// that is, for A::f(int) and A::f(char).
f('a'); // calls f(char)
}
--end example]
9 A name defined by a using-declaration is an alias for its original
declarations so that the using-declaration does not affect the type,
linkage or other attributes of the members referred to.
10If the set of local declarations and using-declarations for a single
name are given in a declarative region,
--they shall all refer to the same entity, or all refer to functions;
or
--exactly one declaration shall declare a class name or enumeration
name and the other declarations shall all refer to the same entity
or all refer to functions; in this case the class name or enumera
tion name is hidden (_basic.scope.hiding_).
11[Example:
namespace A {
int x;
}
namespace B {
int i;
struct g { };
struct x { };
void f(int);
void f(double);
void g(char); // OK: hides struct g
}
void func()
{
int i;
using B::i; // error: i declared twice
void f(char);
using B::f; // fine: each f is a function
f(3.5); // calls B::f(double)
using B::g;
g('a'); // calls B::g(char)
struct g g1; // g1 has class type B::g
using B::x;
using A::x; // fine: hides struct B::x
x = 99; // assigns to A::x
struct x x1; // x1 has class type B::x
}
--end example]
12If a local function declaration has the same name and type as a func
tion introduced by a using-declaration, the program is ill-formed.
[Example:
namespace C {
void f(int);
void f(double);
void f(char);
}
void h()
{
using B::f; // B::f(int) and B::f(double)
using C::f; // C::f(int), C::f(double), and C::f(char)
f('h'); // calls C::f(char)
f(1); // error: ambiguous: B::f(int) or C::f(int) ?
void f(int); // error: f(int) conflicts with C::f(int)
}
--end example]
13When a using-declaration brings names from a base class into a derived
class scope, member functions in the derived class override and/or
hide virtual member functions with the same name and argument types in
a base class (rather than conflicting). [Example:
struct B {
virtual void f(int);
virtual void f(char);
void g(int);
void h(int);
};
struct D : B {
using B::f;
void f(int); // ok: D::f(int) overrides B::f(int);
using B::g;
void g(char); // ok
using B::h;
void h(int); // ok: D::h(int) hides B::h(int)
};
void k(D* p)
{
p->f(1); // calls D::f(int)
p->f('a'); // calls B::f(char)
p->g(1); // calls B::g(int)
p->g('a'); // calls D::g(char)
}
--end example]
14For the purpose of overload resolution, the functions which are intro
duced by a using-declaration into a derived class will be treated as
though they were members of the derived class. In particular, the
implicit this parameter shall be treated as if it were a pointer to
the derived class rather than to the base class. This has no effect
on the type of the function, and in all other respects the function
remains a member of the base class.
15All instances of the name mentioned in a using-declaration shall be
accessible. In particular, if a derived class uses a using-
declaration to access a member of a base class, the member name shall
be accessible. If the name is that of an overloaded member function,
then all functions named shall be accessible.
16The alias created by the using-declaration has the usual accessibility
for a member-declaration. [Example:
class A {
private:
void f(char);
public:
void f(int);
protected:
void g();
};
class B : public A {
using A::f; // error: A::f(char) is inaccessible
public:
using A::g; // B::g is a public synonym for A::g
};
--end example]
17[Note: use of access-declarations (_class.access.dcl_) is deprecated;
member using-declarations provide a better alternative. ]
7.3.4 Using directive [namespace.udir]
1 using-directive:
using namespace ::opt nested-name-specifieropt namespace-name ;
[Note: when looking up a namespace-name is a using-directive, only
namespace names are considered, see _basic.lookup.udir_. ]
2 A using-directive specifies that the names in the nominated namespace
can be used in the scope in which the using-directive appears after
the using-directive. During name look up (_basic.lookup_), the names
appear as if they were declared in the nearest enclosing namespace
which contains both the using-directive and the nominated namespace.
[Note: in this context, "contains" means "contains directly or indi
rectly". ] A using-directive does not add any members to the declara
tive region in which it appears. [Example:
namespace A {
int i;
namespace B {
namespace C {
int i;
}
using namespace A::B::C;
void f1() {
i = 5; // ok, C::i visible in B and hides A::i
}
}
namespace D {
using namespace B;
using namespace C;
void f2() {
i = 5; // ambiguous , B::C::i or A::i ?
}
}
void f3() {
i = 5; // uses A::i
}
}
void f4() {
i = 5; // ill-formed; neither "i" is visible
}
]
3 The using-directive is transitive: if a namespace contains a using-
directive that nominates a second namespace that itself contains
using-directives, the effect is as if the using-directives from the
second namespace also appeared in the first. [Example:
namespace M {
int i;
}
namespace N {
int i;
using namespace M;
}
void f()
{
using namespace N;
i = 7; // error: both M::i and N::i are visible
}
For another example,
namespace A {
int i;
}
namespace B {
int i;
int j;
namespace C {
namespace D {
using namespace A;
int j;
int k;
int a = i; // B::i hides A::i
}
using namespace D;
int k = 89; // no problem yet
int l = k; // ambiguous: C::k or D::k;
int m = i; // B::i hides A::i
int n = j; // D::j hides B::j
}
}
--end example]
4 If a namespace is extended by an extended-namespace-definition after a
using-directive is given, the additional members of the extended
namespace can be used after the extended-namespace-definition.
5 If name look up finds a declaration for a name in two different names
paces, and the declarations do not declare the same entity and do not
declare functions, the use of the name is ill-formed. [Note: in par
ticular, the name of an object, function or enumerator does not hide
the name of a class or enumeration declared in a different namespace.
For example,
namespace A { class X { }; }
namespace B { void X(int); }
using namespace A;
using namespace B;
void f() {
X(1); // error: name X found in two namespaces
}
--end note]
6 During overload resolution, all functions from the transitive search
are considered for argument matching. The set of declarations found
by the transitive search is unordered. [Note: in particular, the
order in which namespaces were considered and the relationships among
the namespaces implied by the using-directives do not cause preference
to be given to any of the declarations found by the search. ] An
ambiguity exists if the best match finds two functions with the same
signature, even if one is in a namespace reachable through using-
directives in the namespace of the other.3) [Example:
namespace D {
int d1;
void f(char);
}
using namespace D;
int d1; // ok: no conflict with D::d1
namespace E {
int e;
void f(int);
}
namespace D { // namespace extension
int d2;
using namespace E;
void f(int);
}
void f()
{
d1++; // error: ambiguous ::d1 or D::d1?
::d1++; // ok
D::d1++; // ok
d2++; // ok: D::d2
e++; // ok: E::e
f(1); // error: ambiguous: D::f(int) or E::f(int)?
f('a'); // ok: D::f(char)
}
--end example]
_________________________
3) During name lookup in a class hierarchy, some ambiguities may be
resolved by considering whether one member hides the other along some
paths (_class.member.lookup_). There is no such disambiguation when
considering the set of names found as a result of following using-
directives.
7.4 The asm declaration [dcl.asm]
1 An asm declaration has the form
asm-definition:
asm ( string-literal ) ;
The meaning of an asm declaration is implementation-defined. [Note:
Typically it is used to pass information through the implementation to
an assembler. ]
7.5 Linkage specifications [dcl.link]
1 Linkage (_basic.link_) between C++ and non-C++ code fragments can be
achieved using a linkage-specification:
linkage-specification:
extern string-literal { declaration-seqopt }
extern string-literal declaration
declaration-seq:
declaration
declaration-seq declaration
The string-literal indicates the required linkage. The meaning of the
string-literal is implementation-defined. Every implementation shall
provide for linkage to functions written in the C programming lan
guage, "C", and linkage to C++ functions, "C++". Default linkage is
"C++". [Example:
complex sqrt(complex); // C++ linkage by default
extern "C" {
double sqrt(double); // C linkage
}
--end example]
+------- BEGIN BOX 2 -------+
This example might need to be revisited depending on what the rules
ultimately are concerning C++ linkage to standard library functions
from the C library.
+------- END BOX 2 -------+
2 Linkage specifications nest. When linkage spefications nest the
innermost one determines the linkage. A linkage specification does
not establish a scope. A linkage-specification can occur only in
namespace scope (_basic.scope_). A linkage-specification for a class
applies to nonmember functions and objects declared within it. A
linkage-specification for a function also applies to functions and
objects declared within it. A linkage declaration with a string that
is unknown to the implementation is ill-formed.
3 If two declarations of the same function or object specify different
linkage-specifications (that is, the linkage-specifications of these
declarations specify different string-literals), the program is ill-
formed if the declarations appear in the same translation unit, and
the one definition rule (_basic.def.odr_) applies if the declarations
appear in different translation units. Except for functions with C++
linkage, a function declaration without a linkage specification shall
not precede the first linkage specification for that function. A
function can be declared without a linkage specification after an
explicit linkage specification has been seen; the linkage explicitly
specified in the earlier declaration is not affected by such a func
tion declaration.
4 At most one of a set of overloaded functions (_over_) with a particu
lar name can have C linkage.
5 Linkage can be specified for objects. [Example:
extern "C" {
// ...
_iobuf _iob[_NFILE];
// ...
int _flsbuf(unsigned,_iobuf*);
// ...
}
--end example] Functions and objects can be declared static or inline
within the {} of a linkage specification. The linkage directive is
ignored for a function or object with internal linkage (_basic.link_).
A function first declared in a linkage specification behaves as a
function with external linkage. [Example:
extern "C" double f();
static double f(); // error
is ill-formed (_dcl.stc_). ] An object defined within an
extern "C" { /* ... */ }
construct is still defined (and not just declared).
6 The linkage of a pointer to function affects only the pointer. When
the pointer is dereferenced, the function to which it refers is con
sidered to be a C++ function. There is no way to specify that the
function to which a function pointer refers is written in another lan
guage.
+------- BEGIN BOX 3 -------+
This is not a wholly satisfactory state of affairs
+------- END BOX 3 -------+
7 Linkage from C++ to objects defined in other languages and to objects
defined in C++ from other languages is implementation-defined and lan
guage-dependent. Only where the object layout strategies of two lan
guage implementations are similar enough can such linkage be achieved.
Taking the address of a function whose linkage is other than C++ or C
produces undefined behavior.
8 When the name of a programming language is used to name a style of
linkage in the string-literal in a linkage-specification, it is recom
mended that the spelling be taken from the document defining that lan
guage, [Example: Ada (not ADA) and Fortran or FORTRAN (depending on
the vintage). ]