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
                  decl-specifier-seqopt init-declarator-listopt ;
  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, can 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
  can  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

7 Only  in function-definitions (_dcl.fct.def_) and in function declara­
  tions for constructors, destructors,  and  type  conversions  can  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-seqopt decl-specifier

2 The  longest sequence of decl-specifiers that could possibly be a type
  name is  taken  as  the  decl-specifier-seq  of  a  declaration.   The
  sequence shall be self-consistent as described below.  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 shall be present to indi­
  cate that the typedef-name Pc is the name being  (re)declared,  rather
  than being part of the decl-specifier sequence.  For 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
  At  most  one  storage-class-specifier  shall  appear in a given decl-
  specifier-seq.   If  a  storage-class-specifier  appears  in  a  decl-
  specifier-seq,  there  can  be  no typedef specifier in the same decl-
  specifier-seq and the init-declarator-list of  the  declaration  shall
  not  be  empty.   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 can 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 can be used in the declara­
  tion of class members and its effect 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­

7 The linkages implied by successive declarations  for  a  given  entity
  shall  agree.  That is, within a given scope, each declaration declar­
  ing the same object name or the same overloading of  a  function  name
  shall  imply  the same linkage.  Each function in a given set of over­
  loaded functions can have a different linkage, however.  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 int 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.

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 can 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 shall be defined in every translation unit in which
  it is used (_basic.def.odr_), and shall have exactly the same  defini­
  tion  in  every  case (see one definition rule, _basic.def.odr_). If a
  function with external linkage is declared inline in  one  translation
  unit, it shall be declared inline in all translation units in which it
  appears.  A call to an inline function shall not precede  its  defini­
  tion.  For example:

          class X {
              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 shall be used only in declarations of nonstatic
  class   member   functions   within   a   class    declaration;    see

5 The explicit specifier shall be used only in declarations of construc­
  tors within a class declaration; see _class.conv.ctor_.

  7.1.3  The typedef specifier                             [dcl.typedef]

1 Declarations containing the decl-specifier typedef declare identifiers
  that can be used later for naming fundamental (_basic.fundamental_) or
  compound (_basic.compound_) types.  The typedef specifier shall not be
  used  in  a  function-definition  (_dcl.fct.def_), and it shall not be
  combined in a decl-specifier-seq with  any  other  kind  of  specifier
  except a type-specifier.
  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.   A  typedef-name  is  thus a synonym for another type.  A
  typedef-name does not introduce a new type the way a class declaration
  (_class.name_) or enum declaration does.  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 can 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 shall 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 shall not be  declared  with  the
  same  name as a typedef-name that is declared in that scope and refers
  to a type other than the class 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  shall not be used after a class, struct, or union prefix
  and not in the names for constructors and destructors within the class
  declaration itself.  For example,
          struct 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
  first  typedef-name  declared by the declaration is used to denote the
  class type in place of the dummy name. For example,
          typedef struct { } S, R; // 'S' is the class name for linkage purposes
  The typedef-name is still only a synonym for the dummy name and  shall
  not  be used where a true class name is required.  Such a class cannot
  have explicit constructors or destructors 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;
  If an unnamed class is defined in a typedef declaration but the decla­
  ration does not declare a class type, the name of the class for  link­
  age purposes is a dummy name. For example,
          typedef struct { }* ps; // 'ps' is not the linkage name of the class

6 A typedef-name that names an enumeration is an enum-name (_dcl.enum_).
  The typedef-name shall 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

  7.1.5  Type specifiers                                      [dcl.type]

1 The type-specifiers are
  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:

  --const  or  volatile  can  be combined with any other type-specifier.
    However, redundant cv-qualifiers are prohibited except  when  intro­
    duced  through  the use of typedefs (_dcl.typedef_) or template type
    arguments (_temp.arg_), in which case  the  redundant  cv-qualifiers
    are ignored.

  --signed or unsigned can be combined with char, long, short, or int.

  --short or long can be combined with int.

  --long can be combined with double.

3 At  least one type-specifier is required in a typedef declaration.  At
  least one type-specifier is required in a function declaration  unless
  it declares a constructor, destructor or type conversion operator.  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.  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.  The cv-qualifiers                               [dcl.type.cv]

1 There     are     two     cv-qualifiers,     const    and    volatile.
  _basic.type.qualifier_ describes how cv-qualifiers affect  object  and
  function types.

2 Unless explicitly declared extern, a const object does not have exter­
  nal linkage and shall be initialized (_dcl.init_;  _class.ctor_).   An
  integral  const  object initialized by an integral constant expression
  can be used in integral constant expressions (_expr.const_).

3 CV-qualifiers are supported by the type system so that they cannot  be
  subverted  without casting (_expr.const.cast_). A pointer or reference
  to a cv-qualified type need not actually  point  or  refer  to  a  cv-
  qualified  object,  but it is treated as if it does; a const-qualified
  access path cannot be used to modify an object even if the object ref­
  erenced  is  a non-const object and can be modified through some other
  access path.

4 Except that any class member declare mutable (_dcl.stc_) can be  modi­
  fied,  any  attempt  to  modify  a  const  object  during its lifetime
  (_basic.stc_) results in undefined behavior.

5 Example
          const int ci = 3;  // cv-qualified (initialized as required)
          ci = 4;            // ill-formed: attempt to modify const
          int i = 2;         // not cv-qualified
          const int* cip;    // pointer to const int
          cip = &i;          // okay: cv-qualified access path to unqualified
          *cip = 4;          // ill-formed: attempt to modify through ptr to const
          int* ip;
          ip = const_cast<int*> cip; // cast needed to convert const int* to int*
          *ip = 4;           // defined: *ip points to i, a non-const object
          const int* ciq = new const int (3); // initialized as required
          int* iq = const_cast<int*> ciq;     // cast required
          iq = 4;            // undefined: modifies a const object

6 Example
          class X {
                  mutable int i;
                  int j;
          class Y { public: X x; }
          const Y y;
          y.x.i++;        // well-formed: mutable member can be modified
          y.x.j++;        // ill-formed: const-qualified member modified
          Y* p = const_cast<Y*>(&y);      // cast away const-ness of y
          p->x.i = 99;    // well-formed: mutable member can be modified
          p->x.j = 99;    // undefined: modifies a const member

7 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 might be
  changed by means undetectable by a compiler.

  +-------                 BEGIN BOX 1                -------+
  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 1                 -------+  Simple type specifiers                      [dcl.type.simple]

1 The simple type specifiers are
                  ::opt nested-name-specifieropt type-name
  The simple-type-specifiers specify either a previously-declared  user-
  defined  type  or  one of the fundamental types (_basic.fundamental_).
  Table 1 summarizes the valid  combinations  of  simple-type-specifiers
  and the types they specify.

        Table 1--simple-type-specifiers and the types they specify

                |Specifier(s)       | Type               |
                |type-name          | the type named     |
                |char               | char               |
                |unsigned char      | unsigned char      |
                |signed char        | signed char        |
                |bool               | bool               |
                |unsigned           | unsigned int       |
                |unsigned int       | unsigned int       |
                |signed             | int                |
                |signed int         | int                |
                |int                | int                |
                |unsigned short int | unsigned short int |
                |unsigned short     | unsigned short int |
                |unsigned long int  | unsigned long int  |
                |unsigned long      | unsigned long int  |
                |signed long int    | long int           |
                |signed long        | long int           |
                |long int           | long int           |
                |long               | long int           |
                |signed short int   | short int          |
                |signed short       | short int          |
                |short int          | short int          |
                |short              | short int          |
                |wchar_t            | wchar_t            |
                |float              | float              |
                |double             | double             |
                |long double        | long double        |
                |void               | void               |
  When  multiple  simple-type-specifiers are allowed, they can be freely
  intermixed with other decl-specifiers in any order.  It is implementa­
  tion-defined  whether  bit-fields  and objects of char type are repre­
  sented as signed or unsigned quantities.  The signed specifier  forces
  char  objects  and bit-fields to be signed; it is redundant with other
  integral types.  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 can
  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.
                  class-key ::opt nested-name-specifieropt identifier
                  enum ::opt nested-name-specifieropt identifier


2 If an elaborated-type-specifier is the sole constituent of a  declara­
  tion, the declaration is ill-formed unless it has one of the following
  --      class-key identifier ;

    in which case the elaborated-type-specifier declares the  identifier
    to  be  a  class-name  in  the  scope  that contains the declaration

3 --      friend class-key identifier ;

    in which case the elaborated-type-specifier declares the  identifier
    to be a class-name in the smallest enclosing non-class, non-function
    prototype scope that contains the declaration;

4 --      friend class-key ::identifier ;
          friend class-key nested-name-specifier identifier ;

    in which case the identifier is resolved  as  when  the  elaborated-
    type-specifier is not the sole constituent of a declaration.

5 If  the  elaborated-type-specifier  is not the sole constituent of the
  declaration, 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 that  contains
  the declaration.

6 The class-key or enum keyword present in the elaborated-type-specifier
  shall agree in kind with the declaration to  which  the  name  in  the
  elaborated-type-specifier  refers.  This rule also applies to the form
  of elaborated-type-specifier that  declares  a  class-name  or  friend
  class  since it can be construed as referring to the definition of the
  class.  Thus, in any elaborated-type-specifier, the enum keyword shall
  be  used  to refer to an enumeration (_dcl.enum_), the union class-key
  shall be used to refer to a union (_class_), and either the  class  or
  struct class-key shall be used to refer to a 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
                  friend struct ::Glob;   // error: Glob is not declared
                                          // cannot introduce a qualified type
                  friend struct Glob;     // ok: Declares Glob in global scope
                  /* ... */

          struct Base {
                  struct Data;                    // ok: Declares nested Data
                  struct ::Data*     thatData;    // ok: Refers to ::Data
                  struct Base::Data* thisData;    // ok: Refers to nested Data

                  friend class ::Data;            // ok: global Data is a friend
                  struct Data { /* ... */ };      // Defines nested Data

                  struct Data;                    // ok: Redeclares nested Data

          struct Data;            // ok: Redeclares Data at global scope

          struct ::Data;          // error: cannot introduce a qualified type
          struct Base::Data;      // error: cannot introduce a qualified type
          struct Base::Datum;     // error: Datum undefined

          struct Base::Data* pBase;       // ok: refers to nested Data

  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 identifieropt { enumerator-listopt }
                  enumerator-list , enumerator-definition
                  enumerator = constant-expression
  The identifiers in an enumerator-list are declared as  constants,  and
  can  appear  wherever  constants  are  required.   If  no  enumerator-
  definitions with =  appear,  then  the  values  of  the  corresponding

  constants  begin at zero and increase by one as the enumerator-list is
  read from left to right.  An enumerator-definition with  =  gives  the
  associated  enumerator the value indicated by the constant-expression;
  subsequent enumerators without initializers continue  the  progression
  from the assigned value.  The constant-expression shall be of integral

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,2) 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 Two enumeration types are layout-compatible if they have the same sets
  of enumerator values.

  +-------                      BEGIN BOX 2                     -------+
  Shouldn't this be the same underlying type?
  +-------                       END BOX 2                      -------+

  2) The type should be larger than int only if the value of an enumera­
  tor won't fit in an int.

8 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­
      enum color { red, yellow, green=20, blue };
      color col = red;
      color* cp = &col;
      if (*cp == blue) // ...
  makes color a type describing various colors, and then declares col as
  an object of that type, and cp as a pointer to an object of that type.
  The possible values of an object of type color are red, yellow, green,
  blue; these values can be converted to the integral values 0,  1,  20,
  and  21.  Since enumerations are distinct types, objects of type color
  can be assigned only values of type color.  For example,
          color c = 1;     // error: type mismatch,
                           // no conversion from int to color
          int i = yellow;  // ok: yellow converted to integral value 1
                           // integral promotion
  See also _diff.anac_.

9 An expression of arithmetic type or of type wchar_t can  be  converted
  to an enumeration type explicitly.  The value is unchanged if it is in
  the range of enumeration values of the enumeration type; otherwise the
  resulting enumeration value is unspecified.

  +-------                      BEGIN BOX 3                     -------+
  This means the program does not crash.
  +-------                       END BOX 3                      -------+

10The  enum-name  and  each  enumerator declared by an enum-specifier is
  declared in the scope that immediately  contains  the  enum-specifier.
  These   names   obey   the  scope  rules  defined  for  all  names  in
  (_basic.scope_) and (_class.scope_).  An enumerator declared in  class
  scope can be referred to using the class member access operators ( ::,
  .  (dot) and -> (arrow)), see _expr.ref_.  For example,
          class X {
              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 one or more translation units.

2 A name declared outside all named  namespaces,  blocks  (_stmt.block_)
  and     classes     (_class_)     has     global    namespace    scope

  7.3.1  Namespace definition                            [namespace.def]

1 The grammar for a namespace-definition is



                  namespace identifier { namespace-body }

                  namespace original-namespace-name  { namespace-body }

                  namespace { namespace-body }


2 The identifier in an original-namespace-definition shall not have been
  previously  defined  in  the declarative region in which the original-
  namespace-definition  appears.   The  identifier   in   an   original-
  namespace-definition  is  the  name of the namespace.  Subsequently in
  that declarative region, it is treated as an  original-namespace-name.

3 The original-namespace-name in an extension-namespace-definition shall
  have previously been defined in  an  original-namespace-definition  in
  the same declarative region.

4 Every  namespace-definition  shall  appear in the global scope or in a
  namespace scope (_basic.scope.namespace_).  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:

                  class-or-namespace-name :: nested-name-specifieropt



2 The  namespace-names in a nested-name-specifier shall have been previ­
  ously defined by a named-namespace-definition  or  a  namespace-alias-

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.  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.3) For example:

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

          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
          }  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.  Namespace member definitions               [namespace.memdef]

1 Members  of  a  namespace  can  be defined within that namespace.  For
          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
          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::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 identifier = 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.  No diagnostic is required for  a  viola­
  tion of this rule by declarations in different translation units.

  7.3.3  The using declaration                         [namespace.udecl]

1 A  using-declaration  introduces a name into the declarative region in
  which the using-declaration appears.  That name is a synonym  for  the
  name of some entity declared elsewhere.
                  using ::opt nested-name-specifier unqualified-id ;
                  using ::  unqualified-id ;

  +-------                      BEGIN BOX 5                     -------+
  There  is  still an open issue regarding the "opt" on the nested-name-
  +-------                       END BOX 5                      -------+

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 shall 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 shall be a member-declaration.  For
          struct X {
                  int i;
                  static int s;
          void f()
                  using X::i;  // error: X::i is a class member
                               // and this is not a member declaration.
                  using X::s;  // error: X::s is a class member
                               // and this is not a member declaration.

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

          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

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
          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 6                     -------+
  For p->g(1) to be unambiguous, the  D::g(int)  synonym  for  B::g(int)
  must  take part in the overload resolution as if it was a member of D,
  though its type must be ``member of B.''  A proper phrasing  for  this
  is being prepared for a vote.
  +-------                       END BOX 6                      -------+

13All  instances  of  the name mentioned in a using-declaration shall be
  accessible.   In  particular,  if  a  derived  class  uses  a   using-
  declaration  to access a member of a base class, the member name shall
  be accessible.  If the name is that of an overloaded member  function,
  then all functions named shall be accessible.

14The alias created by the using-declaration has the usual accessibility
  for a member-declaration.  For example:
          class A {
                  void f(char);
                  void f(int);
                  void g();
          class B : public A {
                  using A::f; // error: A::f(char) is inaccessible
                  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; // well-formed: M::i is not a member of N
                  using namespace N;
                  i = 7;    // error: both M::i and N::i are accessible

4 During  overload  resolution, all functions from the transitive search
  are 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  exam­
          namespace D {
                  int d1;
                  void f(char);
          using namespace D;

          int d1;            // ok: no conflict with D::d1
          namespace E {
                  int e;
                  void f(int);
          namespace D {       // namespace extension
                  int d2;
                  using namespace E;
                  void f(int);

          void f()
                  d1++;      // error: ambiguous ::d1 or D::d1?
                  ::d1++;    // ok
                  D::d1++;   // ok
                  d2++;      // ok: D::d2
                  e++;       // ok: E::e
                  f(1);      // error: ambiguous: D::f(int) or E::f(int)?
                  f('a');    // ok: D::f(char)

  7.4  The asm declaration                                     [dcl.asm]

1 An asm declaration has the form
                  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­

  7.5  Linkage specifications                                 [dcl.link]

1 Linkage  (_basic.link_) between C++ and  non-C++ code fragments can be
  achieved using a linkage-specification:
                  extern string-literal { declaration-seqopt }
                  extern string-literal 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 7                     -------+
  This example might need to be revisited depending on  what  the  rules
  ultimately  are  concerning  C++ linkage to standard library functions
  from the C library.
  +-------                       END BOX 7                      -------+

2 Linkage specifications nest.  A linkage specification does not  estab­
  lish  a  scope.   A  linkage-specification can occur only in namespace
  scope (_basic.scope_).  A linkage-specification for a class applies to
  nonmember  functions  and  objects  declared  within  it.   A linkage-
  specification for a function also applies  to  functions  and  objects
  declared  within  it.   A  linkage  declaration  with a string that is

  unknown to the implementation is ill-formed.

3 If a function has more  than  one  linkage-specification,  they  shall
  agree;  that  is,  they shall specify the same string-literal.  Except
  for functions with C++ linkage, a function declaration without a link­
  age  specification  shall  not precede the first linkage specification
  for that function.  A function can be declared without a linkage spec­
  ification  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 can be declared static or inline within  the  {}
  of  a  linkage  specification.  The linkage directive is ignored for a
  function or object with internal linkage (_basic.link_).   A  function
  first  declared  in a linkage specification behaves as a function with
  external linkage.  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.  Tak­
  ing the address of a function whose linkage is other  than  C++  or  C
  produces undefined behavior.

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