______________________________________________________________________

  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).