______________________________________________________________________ 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: decl-specifier-seqopt init-declarator-listopt ; function-definition template-declaration asm-definition linkage-specification namespace-definition namespace-alias-definition using-declaration using-directive 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.dcls_. Namespace-definitions are described in _namespace.def_, using- declarations are described in _namespace.udecl_ and using-directives are described in _namespace.udir_. The description of the general form of 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 _class.scope_. 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, may have declarations nested within them. Unless otherwise stated, utterances in this chapter 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 the general form of declaration, the optional init-declarator-list may be omitted only when declaring a class (_class_), enumeration (_dcl.enum_) or namespace (_namespace.def_), that is, when the decl- specifier-seq contains either a class-specifier, an elaborated-type- specifier with a class-key (_class.name_), an enum-specifier, or a namespace-definition. In these cases and whenever a class-specifier, enum-specifier, or namespace-definition 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, enumerators, or namespace-name, 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-definitions (_dcl.fct.def_) and in function declara tions for constructors, destructors, and type conversions may the decl-specifier-seq be omitted. 8 Generally speaking, the names declared by a declaration are introduced into the scope in which the declaration occurs. The presence of a friend specifier, certain uses of the elaborated-type-specifier,and using-directives alter this general behavior, however (see _class.friend_, _class.name_ and _namespace.udir_) 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 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 must be self-consistent as described below. For 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 must be present to indicate that the typedef-name Pc is the name being (re)declared, rather than being part of the decl-specifier sequence. For example, void f(const Pc); // void f(char* const) (not const char*) void g(const int Pc); // void g(const int) 3 Note that 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. For example, void h(unsigned Pc); // void h(unsigned int) void k(unsigned int Pc); // void k(unsigned int) 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 may 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 must not be empty. 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 compiler that the object so declared will be heavily used. The hint may be ignored and in most implementations 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 may be used in the declara tion of class members and its affect is described in _class.static_. A name declared with a static specifier in a scope other than class scope (_basic.scope.class_) has internal linkage. For a nonmember function, an inline specifier is equivalent to a static specifier for linkage purposes (_basic.link_) unless the inline declaration 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. A name declared in namespace scope with the extern specifier has external linkage unless the decla ration matches a previous declaration, in which case the name retains the linkage of the previous declaration. An object or function declared at block scope with the extern specifier has external linkage unless the declaration matches a visible declaration of namespace scope that has internal linkage, in which case the object or function has internal linkage and refers to the same object or function denoted by the declaration of namespace scope.1) 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 must agree. That is, within a given scope, each declaration declaring the same object name or the same overloading of a function name must imply the same linkage. Each function in a given set of overloaded functions may have a different linkage, however. For 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 _________________________ 1) Here, ``previously'' includes enclosing scopes. This implies that a name specified static and then specified extern in an inner scope still has internal linkage. extern d; // `d' has external linkage static int d; // error: inconsistent linkage 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. For example, struct S; extern S a; extern S f(); extern void g(S); void h() { g(a); // error: S undefined f(); // error: S undefined } The mutable specifier can be applied only to names of class data mem bers (_class.mem_) and can not be applied to names declared const or static. For example class X { mutable const int* p; // ok mutable int* const q; // ill-formed }; 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 2 The inline specifier is a hint to the compiler that inline substitu tion of the function body is to be preferred to the usual function call implementation. The hint may be ignored. The inline specifier shall not appear on a block scope function declaration. For the link age of inline functions, see _basic.link_ and _dcl.stc_. A function (_dcl.fct_, _class.mfct_, _class.friend_) defined within the class definition is inline by default. 3 An inline function must be defined in every translation unit in which it is used (_basic.def.odr_), and must 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 must be declared inline in all translation units in which it appears. A call to an inline function may not precede its definition. For example: class X { public: int f(); inline int g(); }; void k(X* p) { int i = p->f(); int j = p->g(); // A call appears before X::g is defined // ill-formed // ... } inline int X::f() // Declares X::f as an inline function // A call appears before X::f is defined // ill-formed { // ... } inline int X::g() { // ... } 4 The virtual specifier may be used only in declarations of nonstatic class member functions within a class declaration; see _class.virtual_. 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 may not be used in a function-definition (_dcl.fct.def_), and it may not be com bined 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_. If, in a decl-specifier-seq containing the decl-specifier typedef, there is no type-specifier, or the only type-specifiers are cv-qualifiers, the typedef declaration is ill-formed unless the declaration introduces a type-name-declaration in the scope of a template definition (_temp.res_). 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 declara tion does. For 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 may be used to redefine the name of any type declared in that scope to refer to the type to which it already refers. For example, typedef struct s { /* ... */ } s; typedef int I; typedef int I; typedef I I; 3 In a given scope, a typedef specifier may not be used to redefine the name of any type declared in that scope to refer to a different type. For example, class complex { /* ... */ }; typedef int complex; // error: redefinition Similarly, in a given scope, a class may 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 itself. For example, typedef int complex; class complex { /* ... */ }; // error: redefinition 4 A typedef-name that names a class is a class-name (_class.name_). The typedef-name may not be used after a class, struct, or union prefix and not in the names for constructors and destructors within the class declaration itself. For example, struct S { S(); ~S(); }; typedef struct S T; S a = T(); // ok struct T * p; // error 5 An unnamed class defined in a declaration with a typedef specifier gets a dummy name. For linkage purposes only (_basic.link_), the typedef-name declared by the declaration is used to denote the class type in place of the dummy name. The typedef-name is still only a syn onym for the dummy name and may not be used where a true class name is required. Such a class cannot have explicit constructors or destruc tors because they cannot be named by the user. For example, typedef struct { S(); // error: requires a return type since S is // an ordinary member function, not a constructor } S; 6 A typedef-name that names an enumeration is an enum-name (_dcl.enum_). The typedef-name may not be used after an enum prefix. 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 may be combined with any other type-specifier. --signed or unsigned may be combined with char, long, short, or int. --short or long may be combined with int. --long may 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. If there is no type-specifier or if the only type-specifiers present in a decl-specifier-seq are cv-qualifiers, then the int specifier is assumed as default.2) Regarding the prohibition of the default int specifier in typedef declarations, see _dcl.typedef_; in all other instances, the use of decl-specifier-seqs which contain no simple- type-specifiers (and thus default to plain int) is deprecated. 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] +------- BEGIN BOX 1 -------+ This section covers the same information as section _basic.type.qualifier_. This information should probably be consoli dated in one place. +------- END BOX 1 -------+ 1 The presence of a const specifier in a decl-specifier-seq specifies a const object. Except that any class member declared mutable (_dcl.stc_) may be modified, any attempt to modify a const object after it has been initialized and before it is destroyed results in undefined behavior. _________________________ 2) Redundant cv-qualifiers are allowed to be introduced through the use of typedefs or template type arguments and are ignored. 2 Example class X { public: mutable int i; int j; }; class Y { public: X x; } const Y y; y.x.i++; // defined behavior y.x.j++; // undefined behavior Y* p = const_cast<Y*>(&y); // cast away const-ness of y p->x.i = 99; // defined behavior p->x.j = 99; // undefined behavior Unless explicitly declared extern, a const object does not have exter nal linkage and must be initialized (_dcl.init_; _class.ctor_). An integral const initialized by an integral constant expression may be used in integral constant expressions (_expr.const_). Each element of a const array is const and each non-function, non-static, non-mutable member of a const class object is const (_class.this_). 3 There are no implementation-independent semantics for volatile objects; volatile is a hint to the compiler to avoid aggressive opti mization involving the object because the value of the object may be changed by means undetectable by a compiler. Each element of a volatile array is volatile and each nonfunction, nonstatic member of a volatile class object is volatile (_class.this_). An object may be both const and volatile, with the type-specifiers appearing in either order. +------- BEGIN BOX 2 -------+ Notwithstanding the description above, the semantics of volatile are intended to be the same in C++ as they are in C. However, it's not possible simply to copy the wording from the C standard until we understand the ramifications of sequence points, etc. +------- END BOX 2 -------+ 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 may 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 Generally speaking, the elaborated-type-specifier is used to refer to a previously declared class-name or enum-name even though the name may be hidden by an intervening object, function, or enumerator declara tion (_basic.scope_), but in some cases it also can be used to declare a class-name. 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 of the form class-key identifier ; then the elaborated-type-specifier declares the identifier to be a class-name in the scope that contains the declaration (_class.name_). Otherwise, the identifier following the class-key or enum keyword is resolved as described in _class.scope_ according to its qualifica tions, if any, but ignoring any objects, functions, or enumerators that have been declared. 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 the resolution is unsuccessful, the elaborated-type-specifier is ill-formed unless it is of the simple form class-key identifier. In this case, the identifier is declared in the smallest non-class, non-function prototype scope enclosing the elaborated-type-specifier (_basic.scope_). 3 The class-key or enum keyword present in the elaborated-type-specifier must agree in kind with the declaration to which the name in the elab orated-type-specifier refers. This rule also applies to the form of elaborated-type-specifier that declares a class-name since it can be construed as referring to the definition of the class. Thus, in any elaborated-type-specifier, the enum keyword must be used to refer to an enumeration (_dcl.enum_), the union class-key must be used to refer to a union (_class_), and either the class or struct class-key must be used to refer to a structure (_class_) or to a class declared using the class class-key. For example: struct Node { struct Node* Next; // ok: Refers to Node at global scope struct Data* Data; // ok: Declares type Data // at global scope and member Data }; struct Data { struct Node* Node; // ok: Refers to Node at global scope /* ... */ }; struct Base { struct Data; // ok: Declares nested Data struct ::Data* thatData; // ok: Refers to ::Data struct Base::Data* thisData; // ok: Refers to nested Data struct Data { /* ... */ }; // Defines nested Data struct Data; // ok: Redeclares nested Data }; struct Data; // ok: Redeclares Data at global scope struct ::Data; // error: qualified and nothing declared. struct Base::Data; // error: qualified and nothing declared. struct Base::Datum; // error: Datum undefined struct Base::Data* pBase; // ok: refers to nested Data 7.2 Enumeration declarations [dcl.enum] 1 An enumeration is a distinct type (_basic.fundamental_) with named constants. Its name becomes an enum-name, that is, a reserved word 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 may appear wherever constants are required. If no enumerator- definitions with = appear, then the values of the corresponding con stants 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 must be of integral type. 2 For 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. For 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, not gratu itously larger than int,3) that can represent all enumerator values defined in the enumeration. 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 enumeration 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),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 The value of an enumerator or an object of an enumeration type is con verted to an integer by integral promotion (_conv.prom_). For exam ple, 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 may be assigned only values of type color. For example, color c = 1; // error: type mismatch, // no conversion from int to color _________________________ 3) The type should be larger than int only if the value of an enumera tor won't fit in an int. int i = yellow; // ok: yellow converted to integral value 1 // integral promotion See also _diff.anac_. 8 An expression of arithmetic type or of type wchar_t may 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. +------- BEGIN BOX 3 -------+ This means the program does not crash. +------- END BOX 3 -------+ 9 The 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 (_class.scope_). An enumerator declared in class scope may be referred to using the class member access operators ( ::, . (dot) and -> (arrow)), see _expr.ref_. For 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 // ... } 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 a single translation unit. 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 original-namespace-name: identifier namespace-definition: original-namespace-definition extension-namespace-definition unnamed-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 must appear in the global scope or in a namespace scope (_basic.scope.namespace_). 7.3.1.1 Explict qualification [namespace.qual] +------- BEGIN BOX 4 -------+ The information in this section is very similar to the information provided in section _basic.scope.exqual_. The information should prob ably be consolidated in one place. +------- END BOX 4 -------+ 1 A name in a class or namespace can be accessed using qualification according to the grammar: id-expression: unqualified-id qualified-id nested-name-specifier: class-or-namespace-name :: nested-name-specifieropt class-or-namespace-name: class-name namespace-name namespace-name: original-namespace-name namespace-alias 2 The namespace-names in a nested-name-specifier shall have been previ ously defined by a named-namespace-definition or a namespace-alias- definition. +------- BEGIN BOX 5 -------+ I believe "class-specifier" and "namespace-alias-definition" above should be replaced with "type-name" to include "original-namespace- specifier" and "typedef" as well. +------- END BOX 5 -------+ The class-names in a nested-namespace-specifier shall have been previ ously defined by a class-specifier or a namespace-alias-definition. 3 The search for the initial qualifier preceding any :: operator locates only the names of types or namespaces. The search for a name after a :: locates only names members of a namespace or class. In particular, using-directives (_namespace.udir_) are ignored, as is any enclosing declarative region. 7.3.1.2 Unnamed namespaces [namespace.unnamed] 1 An unnamed-namespace-definition behaves as if it were replaced by namespace unique { namespace-body } using namespace unique; 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.4) For example: _________________________ 4) 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. 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++; // error: A::i undefined j++; // A::unique::j } 7.3.1.3 Namespace scope [namespace.scope] 1 The declarative region of a namespace-definition is its namespace- body. The potential scope denoted by an original-namespace-name is the concatenation of the declarative regions established by each of the namespace-definitions in the same declarative region with that original-namespace-name. Entities declared in a namespace-body are said to be members of the namespace, and names introduced by these declarations into the declarative region of the namespace are said to be member names of the namespace. For example namespace N { int i; int g(int a) { return a; } void k(); void q(); } namespace { int k=1; } namespace N { int g(char a) // overloads N::g(int) { return k+a; // k is from unnamed namespace } int i; // error: duplicate definition void k(); // ok: duplicate function declaration void k() // ok: definition of N::k() { return g(a); // calls N::g(int) } int q(); // error: different return type } 2 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. For example: namespace Outer { int i; namespace Inner { void f() { i++; } // Outer::i int i; void g() { i++; } // Inner::i } } 3 The use of the static keyword is deprecated when declaring objects in a namespace scope (see _future.directions_); the unnamed-namespace provides a superior alternative. 7.3.1.4 Namespace member definitions [namespace.memdef] 1 Members of a namespace can be defined within that namespace. For example: namespace X { void f() { /* ... */ } } 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. For 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 } 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. For example: // Assume f and g have not yet been defined. namespace A { class X { friend void f(X); // declaration of f class Y { friend void g(); }; }; void f(X) { /* ... */} // definition of f declared above X x; void g() { f(x); } // f and g are members 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 } The scope of class names first introduced in elaborated-type- specifiers is described in (_dcl.type.elab_). 4 When an entity declared with the extern specifier 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. For 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 7.3.2 Namespace or class 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 class-or-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. 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. For example, the following 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; 4 A namespace-name 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. 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. using-declaration: using ::opt nested-name-specifier unqualified-id ; using :: unqualified-id ; +------- BEGIN BOX 6 -------+ There is still an open issue regarding the "opt" on the nested-name- specifier. +------- END BOX 6 -------+ 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. For 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) }; 4 A using-declaration used as a member-declaration must refer to a mem ber of a base class of the class being defined. For example: class C { int g(); }; class D2 : public B { using B::f; // ok: B is a base of D using C::g; // error: C isn't a base of D2 }; 5 A using-declaration for a member must declare a member of a derived class. For example: struct X { int i; static int s; }; void f() { using X::i; // error: X::i is a class member using X::s; // error: X::s is a class member } +------- BEGIN BOX 7 -------+ The using-declaration for the static member X::s could be made to work. My recollection is that it was decided not to allow it. +------- END BOX 7 -------+ 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 (as ever). For example: 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 } 7 A using-declaration is a declaration and can therefore be used repeat edly where (and only where) multiple declarations are allowed. For example: namespace A { int i; } void f() { using A::i; using A::i; // ok: double declaration } class B { int i; }; class X : public B { using B::i; using B::i; // error: double member declaration }; +------- BEGIN BOX 8 -------+ This resolution is editorial. +------- END BOX 8 -------+ 8 The entity declared by an 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. For example: 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) } 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. For example namespace B { int i; void f(int); void f(double); } void g() { int i; using B::i; // error: i declared twice void f(char); using B::f; // fine: each f is a function } 11If a local function declaration has the same name and type as a func tion introduced by a using-declaration, the program is ill-formed. For 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) } 12When a using-declaration brings names from a base class into a derived class scope, member functions in the derived class override virtual member functions with the same name and argument types in a base class (rather than conflicting). For 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); // error: D::h(int) conflicts with 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) } +------- BEGIN BOX 9 -------+ Please check the examples above carefully. They reconcile apparently contradictory votes and WP versions. The examples reflect the view that using-declarations and ordinary declarations behave identically for local and class scope except that overriding of virtual functions is allowed. +------- END BOX 9 -------+ 13All instances of the name mentioned in a using-declaration must be accessible. In particular, if a derived class uses a using- declaration to access a member of a base class, the member name must be accessible. If the name is that of an overloaded member function, then all functions named must be accessible. 14The alias created by the using-declaration has the usual accessibility for a member-declaration. For 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 }; 15Use 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 ; 2 A using-directive specifies that the names in the namespace with the given namespace-name, including those specified by any using- directives in that namespace, can be used in the scope in which the using-directive appears after the using directive, exactly as if the names from the namespace had been declared outside a namespace at the points where the namespace was defined. A using-directive does not add any members to the declarative region in which it appears. 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. 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. In particular, a name in a namespace does not hide names in a second namespace which is the subject of a using-directive in the first namespace. For example: namespace M { int i; } namespace N { int i; using namespace M; } void f() { N::i = 7; // error: ambiguous: M::i or N::i? } 4 During overload resolution, all functions from the transitive search must be considered for argument matching. An ambiguity exists if the best match finds two functions with the same signature, even if one might seem to ``hide'' the other in the using-directive lattice. For example: namespace D { int d1; void f(int); 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) } 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 dependent. Typi cally it is used to pass information through the compiler to an assem bler. 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 dependent. Every implementation shall provide for linkage to functions written in the C programming language, "C", and linkage to C++ functions, "C++". Default linkage is "C++". For example, complex sqrt(complex); // C++ linkage by default extern "C" { double sqrt(double); // C linkage } +------- BEGIN BOX 10 -------+ This example may need to be revisited depending on what the rules ultimately are concerning C++ linkage to standard library functions from the C library. +------- END BOX 10 -------+ 2 Linkage specifications nest. A linkage specification does not estab lish a scope. A linkage-specification may 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 a function has more than one linkage-specification, they must agree; that is, they must specify the same string-literal. Except for functions with C++ linkage, a function declaration without a linkage specification may not precede the first linkage specification for that function. A function may 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 function 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. For example, extern "C" { // ... _iobuf _iob[_NFILE]; // ... int _flsbuf(unsigned,_iobuf*); // ... } Functions and objects may 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. For 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 Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages is implementation and language dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved. 7 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, for example, Ada (not ADA) and FORTRAN (not Fortran).