______________________________________________________________________

  3   Basic concepts                                   [basic]

  ______________________________________________________________________

1 [Note: this clause presents the basic concepts of  the  C++  language.
  It  explains  the difference between an object and a name and how they
  relate to the notion of an lvalue.  It introduces the  concepts  of  a
  declaration and a definition and presents C++'s notion of type, scope,
  linkage, and storage duration.  The mechanisms for starting and termi­
  nating  a  program  are  discussed.  Finally, this clause presents the
  fundamental types of the language and lists the ways  of  constructing
  compound types from these.

2 This  clause does not cover concepts that affect only a single part of
  the language.  Such concepts are discussed in the relevant clauses.
  --end note]

3 An  entity  is a value, object, subobject, base class subobject, array
  element, variable, function, set of functions, instance of a function,
  enumerator, type, class member, template, or namespace.

4 A  name  is a use of an identifier (_lex.name_) that denotes an entity
  or label (_stmt.goto_, _stmt.label_).

  +-------                 BEGIN BOX 1                -------+
  We need to specifically define ``variable''.  The preceding  sentences
  say  that it is an ``entity'' that has a name.  Probably a variable is
  ``a declared object that has a name''.
  +-------                  END BOX 1                 -------+

5 Every name that denotes an entity  is  introduced  by  a  declaration.
  Every  name that denotes a label is introduced either by a goto state­
  ment (_stmt.goto_) or a labeled-statement (_stmt.label_).

6 Some names denote types, classes, enumerations, or templates.  In gen­
  eral,  it  is necessary to determine whether or not a name denotes one
  of these entities before parsing the program that  contains  it.   The
  process that determines this is called name lookup (_basic.lookup_).

7 Two names are the same if

  --they are identifiers composed of the same character sequence; or

  --they  are the names of overloaded operator functions formed with the
    same operator; or

  --they are the names of user-defined conversion functions formed  with
    the same type.

8 An  identifier  used in more than one translation unit can potentially
  refer to the same entity in these translation units depending  on  the
  linkage (_basic.link_) of the identifier specified in each translation
  unit.

  3.1  Declarations and definitions                          [basic.def]

1 A declaration (_dcl.dcl_) introduces one or more names into a transla­
  tion  unit  and  specifies  the interpretation and attributes of these
  names.

2 A declaration is a definition unless it declares  a  function  without
  specifying the function's body (_dcl.fct.def_), it contains the extern
  specifier (_dcl.stc_) and neither an initializer nor a  function-body,
  it   declares   a   static   data   member   in  a  class  declaration
  (_class.static_), it is a class name declaration (_class.name_), or it
  is   a   typedef   declaration   (_dcl.typedef_),   a  using  declara­
  tion(_namespace.udecl_), or a using directive(_namespace.udir_).

3 [Example: all but one of the following are definitions:
          int a;                       // defines a
          extern const int c = 1;      // defines c
          int f(int x) { return x+a; } // defines f
          struct S { int a; int b; };  // defines S
          struct X {                   // defines X
              int x;                   // defines nonstatic data member x
              static int y;            // declares static data member y
              X(): x(0) { }            // defines a constructor of X
          };
          int X::y = 1;                // defines X::y
          enum { up, down };           // defines up and down
          namespace N { int d; }       // defines N and N::d
          namespace N1 = N;            // defines N1
          X anX;                       // defines anX
  whereas these are just declarations:
          extern int a;                // declares a
          extern const int c;          // declares c
          int f(int);                  // declares f
          struct S;                    // declares S
          typedef int Int;             // declares Int
          extern X anotherX;           // declares anotherX
          using N::d;                  // declares N::d
   --end example]

4 [Note: in some circumstances, C++  implementations  implicitly  define
  the    default    constructor    (_class.ctor_),    copy   constructor
  (_class.copy_),  assignment  operator  (_class.copy_),  or  destructor
  (_class.dtor_) member functions.  [Example: given

          struct C {
              string s;    // string is the standard library class (_lib.string_)
          };

          int main()
          {
              C a;
              C b = a;
              b = a;
          }
  the  implementation will implicitly define functions to make the defi­
  nition of C equivalent to
          struct C {
              string s;
              C(): s() { }
              C(const C& x): s(x.s) { }
              C& operator=(const C& x) { s = x.s; return *this; }
              ~C() { }
          };
   --end example]  --end note]

5 [Note: a class name can also be implicitly declared by an  elaborated-
  type-specifier (_basic.scope.pdecl_).  ]

  3.2  One definition rule                               [basic.def.odr]

1 No  translation  unit  shall  contain  more than one definition of any
  variable, function, class type, enumeration type or template.

2 A function is used if it is called, its address is taken, it  is  used
  to  form  a pointer to member, or it is a virtual member function that
  is not pure (_class.abstract_).  Every program shall contain at  least
  one  definition  of every function that is used in that program.  That
  definition can appear explicitly in the program, it can  be  found  in
  the  standard  or  a user-defined library, or (when appropriate) it is
  implicitly defined (see _class.ctor_, _class.dtor_ and  _class.copy_).
  If  a  non-virtual  function  is not defined, a diagnostic is required
  only if an attempt is actually made to call that function.  If a  vir­
  tual function is not defined and it is neither called nor used to form
  a pointer to member, no diagnostic is required.

  +-------                 BEGIN BOX 2                -------+
  This  says  nothing  about  user-defined   libraries.    Probably   it
  shouldn't,  but  perhaps it should be more explicit that it isn't dis­
  cussing it.
  +-------                  END BOX 2                 -------+

3 A non-local variable with static storage duration shall  have  exactly
  one  definition in a program unless the variable either has a built-in
  type or is an aggregate and unless it is either unused or used only as
  the operand of the sizeof operator.

  +-------                 BEGIN BOX 3                -------+
  This is still uncertain.
  +-------                  END BOX 3                 -------+

4 Exactly one definition of a class is required in a translation unit if
  the class is used other than in the formation of a pointer  or  refer­
  ence type.

  +-------                 BEGIN BOX 4                -------+
  This  is not quite right, because it is possible to declare a function
  that has an undefined class type as its return type,  that  has  argu­
  ments of undefined class type.
  +-------                  END BOX 4                 -------+

  +-------                 BEGIN BOX 5                -------+
  There  might  be  other  situations  that do not require a class to be
  defined: extern declarations (i.e.  "extern  X  x;"),  declaration  of
  static members, others???
  +-------                  END BOX 5                 -------+

5 [Example: the following complete translation unit is well-formed, even
  though it never defines X:
          struct X;      // declare X as a struct type
          struct X* x1;  // use X in pointer formation
          X* x2;         // use X in pointer formation
   --end example]

6 There can be more than one definition of a class type (_class_),  enu­
  meration  type  (_dcl.enum_),  inline  function  with external linkage
  (_dcl.fct.spec_), class template (_temp_),  non-static  function  tem­
  plate   (_temp.fct_),   static   data   member  of  a  class  template
  (_temp.static_), member function template (_temp.mem.func_),  or  tem­
  plate specialization for which some template parameters are not speci­
  fied (_temp.spec_, _temp.class.spec_) in a program provided that  each
  definition  appears  in a different translation unit, and provided the
  definitions satisfy the following requirements.  Given such an  entity
  named D defined in more than one translation unit, then

  --each  definition  of D shall consist of the same sequence of tokens;
    and

  --in each definition of D, corresponding names, looked up according to
    _basic.lookup_,  shall refer to an entity defined within the defini­
    tion of D, or shall refer to the same entity, after overload resolu­
    tion  (_over.match_) and after matching of partial template special­
    ization (_temp.over_), except that a  name  can  refer  to  a  const
    object  with internal or no linkage if the object has the same inte­
    gral or enumeration type in all definitions of D, and the object  is
    initialized with a constant expression (_expr.const_), and the value
    (but not the address) of the object is used, and the object has  the

    same value in all definitions of D; and

  --in  each  definition of D, the overloaded operators referred to, the
    implicit calls to conversion operators, constructors,  operator  new
    functions  and  operator  delete  functions, shall refer to the same
    function, or to a function defined within the definition of D; and

  --in each definition of D, a default argument used by an (implicit  or
    explicit)  function  call  is  treated as if its token sequence were
    present in the definition of D; that is,  the  default  argument  is
    subject  to  the  three  requirements  described  above (and, if the
    default argument has sub-expressions with  default  arguments,  this
    requirement applies recursively).1)

  --if  D  is  a   class   with   an   implicitly-declared   constructor
    (_class.ctor_),  it  is as if the constructor was implicitly defined
    in every translation unit where it is used, and the implicit defini­
    tion in every translation unit shall call the same constructor for a
    base class or a class member of D.  [Example:
              // translation unit 1:
              struct X {
                      X(int);
                      X(int, int);
              };
              X::X(int = 0) { }
              class D: public X { };
              D d2; // X(int) called by D()

              // translation unit 2:
              struct X {
                      X(int);
                      X(int, int);
              };
              X::X(int = 0, int = 0) { }
              class D: public X { };     // X(int, int) called by D();
                                         // D()'s implicit definition
                                         // violates the ODR
     --end example] If D is a template, and is defined in more than  one
    translation  unit,  then  the  last  four requirements from the list
    above shall apply to names from the template's enclosing scope  used
    in  the  template  definition  (_temp.encl_),  and also to dependent
    names at the point of instantiation (_temp.dep_).   If  the  defini­
    tions  of  D  satisfy all these requirements, then the program shall
    behave as if there were a single definition of D.   If  the  defini­
    tions  of  D do not satisfy these requirements, then the behavior is
    undefined.

  _________________________
  1)  _dcl.fct.default_  describes how default argument names are looked
  up.

  3.3  Declarative regions and scopes                      [basic.scope]

1 Every name is introduced in some portion  of  program  text  called  a
  declarative  region, which is the largest part of the program in which
  that name is valid, that is, in which that name  may  be  used  as  an
  unqualified  name  to refer to the same declaration.  In general, each
  particular name is valid only within some possibly discontiguous  por­
  tion  of  program  text called its scope.  To determine the scope of a
  declaration, it is sometimes convenient  to  refer  to  the  potential
  scope of a declaration.  The scope of a declaration is the same as its
  potential scope unless the potential scope contains  another  declara­
  tion  of the same name.  In that case, the potential scope of the dec­
  laration in the inner (contained) declarative region is excluded  from
  the  scope  of  the  declaration in the outer (containing) declarative
  region.

2 [Example: in
          int j = 24;
          int main()
          {
                  int i = j, j;
                  j = 42;
          }
  the identifier j is declared twice as a name (and  used  twice).   The
  declarative  region  of  the first j includes the entire example.  The
  potential scope of the first j begins immediately  after  that  j  and
  extends to the end of the program, but its (actual) scope excludes the
  text between the , and the }.  The declarative region  of  the  second
  declaration of j (the j immediately before the semicolon) includes all
  the text between { and }, but its potential scope excludes the  decla­
  ration  of i.  The scope of the second declaration of j is the same as
  its potential scope.  ]

3 [Note: the name look up rules are summarized in _basic.lookup_.  ]

  3.3.1  Point of declaration                        [basic.scope.pdecl]

1 The point of declaration for a name is immediately after its  complete
  declarator (_dcl.decl_) and before its initializer (if any), except as
  noted below.  [Example:
      int x = 12;
      { int x = x; }
  Here the second x is initialized with its own  (indeterminate)  value.
  ]

2 [Note:  a nonlocal name remains visible up to the point of declaration
  of the local name that hides it.  [Example:
      const int  i = 2;
      { int  i[i]; }
  declares a local array of two integers.  ] ]

3 The point of declaration for an enumerator is  immediately  after  its
  enumerator-definition.  [Example:

          const int x = 12;
          { enum { x = x }; }
  Here,  the  enumerator x is initialized with the value of the constant
  x, namely 12.  ]

4 The point of declaration of a class first declared in  an  elaborated-
  type-specifier is as follows:

  --if the elaborated-type-specifier has the form:
              class-key identifier ;
    the elaborated-type-specifier declares the identifier to be a class-
    name in the scope that contains the declaration, otherwise

  --if the elaborated-type-specifier has the form
              class-key identifier ...
    the identifier is declared as a  class-name  in  the  smallest  non-
    class, non-function prototype scope that contains the declaration.

  [Note:  except  for the friend class declaration case mentioned below,
  any other form of elaborated-type-specifier must refer to  an  already
  declared class-name or enum-name; see _basic.lookup.elab_.  ]

5 A class declared as a friend with a declaration of the form:
          friend class-key identifier ;
  and  not  previously  declared is introduced in the smallest enclosing
  non-class scope that contains  the  friend  declaration.   A  function
  declared as a friend and not previously declared, is introduced in the
  smallest enclosing non-class scope that contains the  friend  declara­
  tion.  [Note: when looking for a prior declaration of a class or func­
  tion introduced by a friend declaration, scopes outside of the  inner­
  most  enclosing  namespace  scope  are  not  considered;  see  _names­
  pace.memdef_.  ]

6 [Note: For point of instantiation of a template, see _temp.inst_.  ]

  3.3.2  Local scope                                 [basic.scope.local]

1 A name declared in a block (_stmt.block_) is local to that block.  Its
  potential    scope    begins    at    its    point    of   declaration
  (_basic.scope.pdecl_) and ends at the end of its declarative region.

2 The potential scope of a function parameter name in a function defini­
  tion  (_dcl.fct.def_)  begins  at its point of declaration and ends at
  the end of the outermost block of the function definition.  A  parame­
  ter  name  shall not be redeclared in the outermost block of the func­
  tion definition.

3 The name in a catch exception-declaration is local to the handler  and
  shall not be redeclared in the outermost block of the handler.

4 Names  declared in the for-init-statement, and in the condition of if,
  while, for, and switch statements are local to the if, while, for,  or
  switch  statement  (including the controlled statement), and shall not

  be redeclared in a subsequent condition of that statement nor  in  the
  outermost  block  (or,  for  the  if  statement,  any of the outermost
  blocks) of the controlled statement; see _stmt.select_.

  3.3.3  Function prototype scope                    [basic.scope.proto]

1 In a function declaration, or in any function  declarator  except  the
  declarator  of a function definition (_dcl.fct.def_), names of parame­
  ters (if supplied) have function prototype scope, which terminates  at
  the end of the nearest enclosing function declarator.

  3.3.4  Function scope

1 Labels  (_stmt.label_) have function scope and may be used anywhere in
  the function in which they are declared.  Only  labels  have  function
  scope.

  3.3.5  Namespace scope                         [basic.scope.namespace]

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.  A namespace member name has  names­
  pace  scope.   Its  potential  scope  includes  its namespace from the
  name's point of declaration (_basic.scope.pdecl_) onwards, as well  as
  the  potential  scope  of  any using directive (_namespace.udir_) that
  nominates its namespace.  [Example:
          namespace N {
                  int i;
                  int g(int a) { return a; }
                  int k();
                  void q();
          }
          namespace { int l=1; }
          // the potential scope of l is from its point of declaration
          // to the end of the translation unit
          namespace N {
                  int g(char a)         // overloads N::g(int)
                  {
                          return l+a;   // l is from unnamed namespace
                  }
                  int i;                // error: duplicate definition
                  int k();              // ok: duplicate function declaration
                  int k()               // ok: definition of N::k()
                  {
                          return g(i);  // calls N::g(int)
                  }
                  int q();              // error: different return type
          }
   --end example]

2 A namespace member can also be referred to after the :: scope  resolu­
  tion  operator (_expr.prim_) applied to the name of its namespace; see
  _namespace.qual_.

3 A  name   declared   outside   all   named   or   unnamed   namespaces
  (_basic.namespace_),  blocks  (_stmt.block_) and classes (_class_) has
  global namespace scope (also  called  global  scope).   The  potential
  scope   of   such   a   name   begins  at  its  point  of  declaration
  (_basic.scope.pdecl_) and ends at the end of the translation unit that
  is  its  declarative  region.   Names declared in the global namespace
  scope are said to be global.

  3.3.6  Class scope                                 [basic.scope.class]

1 The following rules describe the scope of names declared in classes.

    1)The potential scope of a name declared in  a  class  consists  not
      only  of  the  declarative region following the name's declarator,
      but also of all function bodies, default arguments, and  construc­
      tor  ctor-initializers  in  that  class  (including such things in
      nested classes).

    2)A name N used in a class S shall refer  to  the  same  declaration
      when  re-evaluated in its context and in the completed scope of S.

    3)If reordering member declarations in a class yields  an  alternate
      valid  program  under  (1) and (2), the program's behavior is ill-
      formed, no diagnostic is required.

    4)A name declared within a member function hides  a  declaration  of
      the same name whose scope extends to or past the end of the member
      function's class.

    5)The potential scope of a declaration that extends to or  past  the
      end  of  a class definition also extends to the regions defined by
      its member definitions, even if the members are defined  lexically
      outside  the  class (this includes static data member definitions,
      nested class definitions and member function definitions (that is,
      the   parameter-declaration-clause   including  default  arguments
      (_dcl.fct.default_), the member function body and, for constructor
      functions        (_class.ctor_),        the       ctor-initializer
      (_class.base.init_)).  [Example:
                  typedef int  c;
                  enum { i = 1 };
                  class X {
                      char  v[i];  // error: 'i' refers to ::i
                                   // but when reevaluated is X::i
                      int  f() { return sizeof(c); }  // okay: X::c
                      char  c;
                      enum { i = 2 };
                  };

                  typedef char*  T;
                  struct Y {
                      T  a;    // error: 'T' refers to ::T
                               // but when reevaluated is Y::T
                      typedef long  T;
                      T  b;
                  };
                  struct Z {
                      int  f(const R);  // error: 'R' is parameter name
                                        // but swapping the two declarations
                                        // changes it to a type
                      typedef int  R;
                  };
       --end example]

2 The name of a class member shall only be used as follows:

  --in the scope of its class (as described above) or  a  class  derived
    (_class.derived_) from its class,

  --after  the  .  operator  applied to an expression of the type of its
    class (_expr.ref_) or a class derived from its class,

  --after the -> operator applied to a pointer to an object of its class
    (_expr.ref_) or a class derived from its class,

  --after  the :: scope resolution operator (_expr.prim_) applied to the
    name of its class or a class derived from its class,

  --or after a using declaration (_namespace.udecl_).

3 [Note: The  scope  of  names  introduced  by  friend  declarations  is
  described in _basic.scope.pdecl_.  ]

  3.3.7  Name hiding                                [basic.scope.hiding]

1 A name can be hidden by an explicit declaration of that same name in a
  nested declarative region or derived class (_class.member.lookup_).

2 A class name (_class.name_) or enumeration name  (_dcl.enum_)  can  be
  hidden  by  the name of an object, function, or enumerator declared in
  the same scope.  If a class or enumeration name and an  object,  func­
  tion, or enumerator are declared in the same scope (in any order) with
  the same name, the class or enumeration name is  hidden  wherever  the
  object, function, or enumerator name is visible.

3 In a member function definition, the declaration of a local name hides
  the declaration of a member of the  class  with  the  same  name;  see
  _basic.scope.class_.   The  declaration of a member in a derived class
  (_class.derived_) hides the declaration of a member of a base class of
  the same name; see _class.member.lookup_.

4 If a name is in scope and is not hidden it is said to be visible.

  3.4  Name look up                                       [basic.lookup]

1 The  name  look up rules apply uniformly to all names (including type­
  def-names  (_dcl.typedef_),  namespace-names  (_basic.namespace_)  and
  class-names  (_class.name_)) wherever the grammar allows such names in
  the context discussed by a particular rule.  Name look  up  associates
  the use of a name with a declaration (_basic.def_) of that name.  Name
  look up shall find  an  unambiguous  declaration  for  the  name  (see
  _class.member.lookup_).  Name look up may associate more than one dec­
  laration with a name if it finds the name to be a function  name;  the
  declarations   are   said  to  form  a  set  of  overloaded  functions
  (_over.load_).  Overload resolution (_over.match_) takes  place  after
  name  look  up  has  succeeded.  The access rules (_class.access_) are
  considered only once name look up and function overload resolution (if
  applicable)  have  succeeded.  Only after name look up, function over­
  load resolution (if applicable) and access checking have succeeded are
  the  attributes  introduced  by the name's declaration used further in
  expression processing (_expr_).

2 [Note: _basic.link_ discusses linkage issues.  The notions  of  scope,
  point  of  declaration and name hiding are discussed in _basic.scope_.
  ]

  3.4.1  Unqualified name look up                  [basic.lookup.unqual]

1 In all the cases listed in this subclause, the scopes are searched for
  a  declaration in the order listed in each of the respective category;
  name look up ends as soon as a declaration is found for the name.   If
  no declaration is found, the program is ill-formed.

2 The  declarations  from  the  namespace nominated by a using-directive
  become visible in  a  namespace  enclosing  the  using-directive;  see
  _namespace.udir_.   For  the  purpose  of the unqualified name look up
  rules described in this subclause, the declarations from the namespace
  nominated by the using-directive are considered members of the enclos­
  ing namespace.

3 A name used in global scope, outside of any function, class  or  user-
  declared  namespace, shall be declared before its use in global scope.

4 A name used in a user-declared namespace outside of the definition  of
  any  function or class shall be declared before its use in that names­
  pace or before its use in a namespace enclosing its namespace.

5 A name used in the definition of a function2)  that  is  a  member  of
  namespace N (where, only for the purpose of exposition, N could repre­
  sent the global scope) shall be declared before its use in  the  block
  _________________________
  2) This refers to unqualified names following the function declarator;
  such a name may be used as a type or as a default argument name in the
  parameter-declaration-clause, or may be used in the function body.

  in  which  it is used or in one of its enclosing blocks (_stmt.block_)
  or, shall be declared before its use in namespace N  or,  if  N  is  a
  nested  namespace,  shall  be  declared  before  its use in one of N's
  enclosing namespaces.  [Example:
          namespace A {
                  namespace N {
                          void f();
                  }
          }
          void A::N::f() {
                  i = 5;
                  // The following scopes are searched for a declaration of i:
                  // 1) function scope of A::N::f, before the use of i
                  // 2) scope of namespace N
                  // 3) scope of namespace A
                  // 4) global scope, before the definition of A::N::f
          }
   --end example]

6 A name used in the definition of a class3) X outside of a member func­
  tion  body  or nested class definition shall be declared in one of the
  following ways:

  --before its use in class X or be a  member  of  a  base  class  of  X
    (_class.member.lookup_), or

  --if X is a nested class of class Y (_class.nest_), before the defini­
    tion of X in Y, or shall be a member of a base class of Y (this look
    up  applies  in  turn  to  Y's  enclosing classes, starting with the
    innermost enclosing class),4) or

  --if X is a local class (_class.local_) or is  a  nested  class  of  a
    local  class,  before the definition of class X in a block enclosing
    the definition of class X, or

  --if X is a member of namespace N, or is a nested  class  of  a  class
    that  is a member of N, or is a local class or a nested class within
    a local class of a function that is a member of N, before the  defi­
    nition  of  class X in namespace N or in one of N's enclosing names­
    paces.

  [Example:

  _________________________
  3) This refers to unqualified names following the class name;  such  a
  name may be used as a base class name or may be used in the class def­
  inition.
  4) This look up applies whether the definition of X is  nested  within
  Y's  definition or whether X's definition appears in a namespace scope
  enclosing Y's definition (_class.nest_).

          namespace M {
                  class B { };
          }
          namespace N {
                  class Y : public M::B {
                          class X {
                                  int a[i];
                          };
                  };
          }
          // The following scopes are searched for a declaration of i:
          // 1) scope of class N::Y::X, before the use of i
          // 2) scope of class N::Y, before the definition of N::Y::X
          // 3) scope of N::Y's base class M::B
          // 4) scope of namespace N, before the definition of N::Y
          // 5) global scope, before the definition of N
   --end example] [Note: when looking for a prior declaration of a class
  or  function introduced by a friend declaration, scopes outside of the
  innermost enclosing namespace scope are not  considered;  see  _names­
  pace.memdef_.   ]  [Note:  _basic.scope.class_  further  describes the
  restrictions on the use of names in a class definition.   _class.nest_
  further describes the restrictions on the use of names in nested class
  definitions.  _class.local_ further describes the restrictions on  the
  use of names in local class definitions.  ]

7 A  name used in the definition of a function that is a member function
  (_class.mfct_)5) of class X shall be declared in one of the  following
  ways:

  --before  its  use in the block in which it is used or in an enclosing
    block (_stmt.block_), or

  --shall be a member of class X or be a member of a  base  class  of  X
    (_class.member.lookup_), or

  --if  X is a nested class of class Y (_class.nest_), shall be a member
    of Y, or shall be a member of a  base  class  of  Y  (this  look  up
    applies  in  turn to Y's enclosing classes, starting with the inner­
    most enclosing class),6) or

  --if X is a local class (_class.local_) or is  a  nested  class  of  a
    local  class,  before the definition of class X in a block enclosing
    the definition of class X, or
  _________________________
  5) That is, an unqualified name  following  the  function  declarator;
  such a name may be used as a type or as a default argument name in the
  parameter-declaration-clause, or may be used in the function body, or,
  if  the  function is a constructor, may be used in the expression of a
  mem-initializer.
  6) This look up applies whether the member function is defined  within
  the definition of class X or whether the member function is defined in
  a namespace scope enclosing X's definition.

  --if X is a member of namespace N, or is a nested  class  of  a  class
    that  is a member of N, or is a local class or a nested class within
    a local class of a function that is a member of N, before the member
    function definition, in namespace N or in one of N's enclosing named
    namespaces.

  [Example:
          class B { };
          namespace M {
                  namespace N {
                          class X : public B {
                                  void f();
                          };
                  }
          }
          void M::N::X::f() {
                  i = 16;
          }
          // The following scopes are searched for a declaration of i:
          // 1) function scope of M::N::X::f, before the use of i
          // 2) scope of class M::N::X
          // 3) scope of M::N::X's base class B
          // 4) scope of namespace M::N
          // 5) scope of namespace M
          // 6) global scope, before the definition of M::N::X::f
    --end  example]  [Note:  _class.mfct_  and  _class.static_   further
  describe the restrictions on the use of names in member function defi­
  nitions.  _class.nest_ further describes the restrictions on  the  use
  of  names  in  the  scope  of  nested  classes.  _class.local_ further
  describes the restrictions on the use of names in local class  defini­
  tions.  ]

8 Name  look  up  for a name used in the definition of a friend function
  (_class.friend_) defined inline in the class granting friendship shall
  proceed  as  described for look up in member function definitions.  If
  the friend function is not defined in the class  granting  friendship,
  name  look  up  in  the  friend  function  definition shall proceed as
  described for look up in namespace member function definitions.

9 A name used in a function parameter-declaration-clause  as  a  default
  argument  (_dcl.fct.default_)  or  used  in  the  expression of a mem-
  initializer (_class.base.init_) is looked up as if the name were  used
  in the outermost block of the function definition.  In particular, the
  function parameter names are visible for name look up in default argu­
  ments  and  in  mem-initializers.   [Note:  _dcl.fct.default_  further
  describes the restrictions on the use of names in  default  arguments.
  _class.base.init_  further  describes  the  restrictions on the use of
  names in a ctor-initializer.  ]

10A name  used  in  the  definition  of  a  static  member  of  class  X
  (_class.static.data_) (after the qualified-id of the static member) is
  looked up as if the name was used in a member function of  X.   [Note:
  _class.static.data_  further  describes the restrictions on the use of

  names in the definition of a static data member.  ]

  +-------                 BEGIN BOX 6                -------+
  This subclause should probably say something about  name  look  up  in
  template definitions.
  +-------                  END BOX 6                 -------+

  3.4.2  Qualified name look up                      [basic.lookup.qual]

1 The  name  of a class or namespace member can be referred to after the
  :: scope resolution operator (_expr.prim_) applied to  a  nested-name-
  specifier  that  nominates its class or namespace.  During the look up
  for a name preceeding the :: scope  resolution  operator,  only  class
  names  and  namespace  names are considered.  A class-name hidden by a
  name that is not a type name or  namespace-name  is  still  found  and
  used.   The  class-name shall have been previously declared by a class
  declaration (_class_).  A namespace-name hidden by a name that is  not
  a  type  name  is still found and used.  The namespace-name shall have
  been previously defined either by a  named-namespace-definition  or  a
  namespace-alias-definition (_namespace.def_).  [Example:
          class A {
          public:
                  static int n;
          };
          int main()
          {
                  int A;
                  A::n = 42;          // OK
                  A b;                // ill-formed: A does not name a type
          }
   --end example]

2 [Note: Multiply qualified names, such as N1::N2::N3::n, can be used to
  refer to members of nested classes (_class.nest_) or members of nested
  namespaces.  ]

3 In  a  declaration in which the declarator-id is a qualified-id, names
  used before the qualified-id being  declared  are  looked  up  in  the
  defining  namespace scope; names following the qualified-id are looked
  up in the scope of the member's class or namespace.  [Example:
          class X { };
          class C {
                  class X { };
                  const int number = 50;
                  static X arr[number];
          };
          X C::arr[number];  // ill-formed:
                             // equivalent to:  X  C::arr[C::number];
                             // not to:  C::X  C::arr[C::number];
   --end example]

4 A name prefixed by the unary scope operator :: (_expr.prim_) is looked
  up  in  global  scope,  in the translation unit where it is used.  The
  name shall be declared in global namespace scope or shall  be  a  name
  whose declaration is visible in global scope because of a using direc­
  tive (_namespace.qual_).  The use of :: allows a  global  name  to  be
  referred    to    even    if    its   identifier   has   been   hidden
  (_basic.scope.hiding_).

  3.4.2.1  Class members                                    [class.qual]

1 If the nested-name-specifier of a qualified-id nominates a class,  the
  name  specified  after  the  nested-name-specifier is looked up in the
  scope of the class.  The name shall represent a member of  that  class
  or  a  member  of  one  of its base classes (_class.derived_).  [Note:
  _class.member.lookup_ describes how name look  up  proceeds  in  class
  scope.  ]

2 A class member name hidden by a name in a nested declarative region or
  by the name of a derived class member can still be found if  qualified
  by the name of its class followed by the :: operator.

  3.4.2.2  Namespace members                            [namespace.qual]

1 If  the nested-name-specifier of a qualified-id nominates a namespace,
  the name specified after the nested-name-specifier is looked up in the
  scope of the namespace.

2 Given  X::m,  where  X is a namespace, if m is declared directly in X,
  let S be the set of all such declarations of m.  Else if there are  no
  using-directives in X, S is the empty set.  Else let S be the union of
  all sets of declarations of m found in the  namespaces  designated  by
  the  using-directives in X.  If m is declared directly in these names­
  paces, let S be the set of all such declarations of m.  Else if  these
  namespaces  do  not  contain any using-directives, S is the empty set.
  Else, this search is applied recursively to the namespaces  designated
  by the using-directives in these namespaces.  No namespace is searched
  more than once in the lookup of a name.  If S is  the  empty  set  the
  program is ill-formed, otherwise S is the required set of declarations
  of m.  If S has exactly one member then X::m refers  to  that  member.
  Otherwise  if the use of m is not one that allows a unique declaration
  to be chosen from S, the program is  ill-formed.   [Note:  the  choice
  could  be  made  by  overload  resolution (_over.match_) or resolution
  between class names and non-class names (_class.name_).  For example:
          int x;
          namespace Y {
                  void f(float);
                  void h(int);
          }
          namespace Z {
                  void h(float);
          }

          namespace A {
                  using namespace Y;
                  void f(int);
                  void g(int);
                  int i;
          }
          namespace B {
                  using namespace Z;
                  void f(char);
                  int i;
          }
          namespace AB {
                  using namespace A;
                  using namespace B;
                  void g();
          }
          void h()
          {
                  AB::g();     // g is declared directly in AB,
                               // therefore S is { AB::g() } and AB::g() is chosen
                  AB::f(1);    // f is not declared directly in AB so the rules are
                               // applied recursively to A and B;
                               // namespace Y is not searched and Y::f(float)
                               // is not considered;
                               // S is { A::f(int), B::f(char) } and overload
                               // resolution chooses A::f(int)
                  AB::f('c');  // as above but resolution chooses B::f(char)

                  AB::x++;     // x is not declared directly in AB, and
                               // is not declared in A or B, so the rules are
                               // applied recursively to Y and Z,
                               // S is { } so the program is ill-formed
                  AB::i++;     // i is not declared directly in AB so the rules are
                               // applied recursively to A and B,
                               // S is { A::i, B::i } so the use is ambiguous
                               // and the program is ill-formed
                  AB::h(16.8); // h is not declared directly in AB and
                               // not declared directly in A or B so the rules are
                               // applied recursively to Y and Z,
                               // S is { Y::h(int), Z::h(float) } and overload
                               // resolution chooses Z::h(float)
          }

3 The same declaration found more than once is not an ambiguity (because
  it is still a unique declaration). For example:
          namespace A {
                  int a;
          }
          namespace B {
                  using namespace A;
          }

          namespace C {
                  using namespace A;
          }
          namespace BC {
                  using namespace B;
                  using namespace C;
          }
          void f()
          {
                  BC::a++;  // ok: S is { A::a, A::a }
          }
          namespace D {
                  using A::a;
          }
          namespace BD {
                  using namespace B;
                  using namespace D;
          }
          void g()
          {
                  BD::a++;  // ok: S is { A::a, A::a }
          }

4 Since  each referenced namespace is searched at most once, the follow­
  ing is well-defined:
          namespace B {
                  int b;
          }
          namespace A {
                  using namespace B;
                  int a;
          }
          namespace B {
                  using namespace A;
          }
          void f()
          {
                  A::a++;  // ok: a declared directly in A, S is { A::a }
                  B::a++;  // ok: both A and B searched (once), S is { A::a }
                  A::b++;  // ok: both A and B searched (once), S is { B::b }
                  B::b++;  // ok: b declared directly in B, S is { B::b }
          }
   --end note]

5 During the look up of a qualified namespace member name, if  the  look
  up  finds more than one declaration of the member, and if one declara­
  tion introduces a class name or enumeration name and the other  decla­
  rations either introduce the same object, the same enumerator or a set
  of functions, the non-type name hides the class or enumeration name if
  and  only  if  the declarations are from the same namespace; otherwise
  (the declarations are from different namespaces), the program is  ill-
  formed.  [Example:

          namespace A {
                  struct x { };
                  int x;
                  int y;
          }
          namespace B {
                  struct y {};
          }
          namespace C {
                  using namespace A;
                  using namespace B;
                  int i = C::x; // ok, A::x (of type 'int')
                  int j = C::y; // ambiguous, A::y or B::y
          }
   --end example]

6 In  a declaration for a namespace member in which the declarator-id is
  a qualified-id, given that the qualified-id for the  namespace  member
  has the form
          nested-name-specifier unqualified-id
  the  unqualified-id shall name a member of the namespace designated by
  the nested-name-specifier.  [Example:
          namespace A {
                  namespace B {
                          void f1(int);
                  }
                  using namespace B;
          }
          void A::f1(T){}  // ill-formed, f1 is not a member of A
   --end example] However, in such namespace  member  declarations,  the
  nested-name-specifier  may rely on using-directives to implicitly pro­
  vide the initial part of the nested-name-specifier.  [Example:
          namespace A {
                  namespace B {
                          void f1(int);
                  }
          }
          namespace C {
                  namespace D {
                          void f1(int);
                  }
          }
          using namespace A;
          using namespace C::D;
          void B::f1(int){}  // okay, defines A::B::f1(int)
          void f1(int){}  // okay, defines C::D::f1(int)
   --end example]

  3.4.3  Elaborated type specifiers                  [basic.lookup.elab]

1 An elaborated-type-specifier may be used  to  refer  to  a  previously
  declared  class-name or enum-name even though the name has been hidden
  by  an  intervening  object,  function,  or   enumerator   declaration

  (_basic.scope.hiding_).   The  class-name  or  enum-name in the elabo­
  rated-type-specifier may either be a simple identifer or be  a  quali­
  fied-id.

2 If  the  name  in the elaborated-type-specifier is a simple identifer,
  and unless the elaborated-type-specifier has the following form:
          class-key identifier ;
  the identifier is looked up  according  to  _basic.lookup.unqual_  but
  ignoring   any  objects,  functions  or  enumerators  that  have  been
  declared.  If this name look up finds a typedef_name, the  elaborated-
  type-specifier is ill-formed.  If the elaborated-type-specifier refers
  to an enum-name and this look up does not find a  previously  declared
  enum-name, the elaborated-type-specifier is ill-formed.  If the elabo­
  rated-type-specifier refers to an class-name and this look up does not
  find  a  previously  declared  class-name,  or if the elaborated-type-
  specifier has the form:
          class-key identifier ;
  the elaborated-type-specifier is a  declaration  that  introduces  the
  class-name as described in _basic.scope.pdecl_.

3 If  the  name  is  a qualified-id, the name is looked up according its
  qualifications, as described in _basic.lookup.qual_, but ignoring  any
  objects,  functions  or  enumerators that have been declared.  If this
  name look up finds a typedef_name,  the  elaborated-type-specifier  is
  ill-formed.   If this name look up does not find a previously declared
  class-name or enum-name, the elaborated-type-specifier is  ill-formed.
  [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
                  friend class Data;              // ok: nested 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

   --end example]

  3.4.4  Class member access                     [basic.lookup.classref]

1 A name specified after the . operator or -> operator of a class member
  access is looked up as specified in _expr.ref_.

  +-------                 BEGIN BOX 7                -------+
  This subclause needs work.  _expr.ref_ is not really clear in describ­
  ing how names after the . operator and -> operator are looked up.  See
  core issue 452a.
  +-------                  END BOX 7                 -------+

  3.4.5  Using directives and namespace aliases      [basic.lookup.udir]

1 When  looking  up  a namespace-name in a using-directive or namespace-
  alias-definition, only namespace names are considered.

  3.5  Program and linkage                                  [basic.link]

1 A program consists of one or more  translation  units  (_lex_)  linked
  together.   A translation unit consists of a sequence of declarations.
          translation unit:
                  declaration-seqopt

2 A name is said to have linkage when it might denote the  same  object,
  reference,  function,  type,  template,  namespace  or value as a name
  introduced by a declaration in another scope:

  --When a name has external linkage,  the  entity  it  denotes  can  be
    referred  to by names from scopes of other translation units or from
    other scopes of the same translation unit.

  --When a name has internal linkage,  the  entity  it  denotes  can  be
    referred to by names from other scopes in the same translation unit.

  --When a name has no linkage, the entity it denotes cannot be referred
    to by names from other scopes.

3 A  name  having namespace scope (_basic.scope.namespace_) has internal
  linkage if it is the name of

  --an object that is  explicitly  declared  static  or,  is  explicitly
    declared const and neither explicitly declared extern nor previously
    declared to have external linkage; or

  --a function that is explicitly  declared  static  or,  is  explicitly
    declared  inline  and  neither explicitly declared extern nor previ­
    ously declared to have external linkage; or

  --the name of a data member of an anonymous union.

4 A name having namespace scope has external linkage if it is  the  name
  of

  --an object, unless it has internal linkage; or

  --a function, unless it has internal linkage; or

  --a  named  class  (_class_), or an unnamed class defined in a typedef
    declaration in which the class has the typedef name for linkage pur­
    poses (_dcl.typedef_); or

  --a  named enumeration (_dcl.enum_), or an unnamed enumeration defined
    in a typedef declaration in which the enumeration  has  the  typedef
    name for linkage purposes (_dcl.typedef_); or

  --an enumerator belonging to an enumeration with external linkage; or

  --a template (_temp_); or

  --a  namespace  (_basic.namespace_),  unless  it is declared within an
    unnamed namespace.

5 In addition, a name of class scope has external linkage if the name of
  the class has external linkage.

6 The  name of a function declared in a block scope has linkage.  If the
  block scope function declaration matches a prior  visible  declaration
  of  the  same  function, the function name receives the linkage of the
  previous declaration; otherwise, it receives  external  linkage.   The
  name  of  an  object  declared by a block scope extern declaration has
  linkage.  If the block scope declaration matches a prior visible  dec­
  laration  of  the  same object, the name introduced by the block scope
  declaration receives the linkage of the previous  declaration;  other­
  wise, it receives external linkage.  [Example:
          static void f();
          static int i = 0;
          void g() {
                  extern void f(); // internal linkage
                  int i; // 'i' has no linkage
                  {
                          extern void f(); // internal linkage
                          extern int i; // external linkage
                  }
          }
   --end example]

7 Names not covered by these rules have no linkage.  Moreover, except as
  noted, a name declared in a local scope (_basic.scope.local_)  has  no
  linkage.  A name with no linkage (notably, the name of a class or enu­
  meration declared in a local scope (_basic.scope.local_)) shall not be
  used to declare an entity with linkage.  If a declaration uses a type­
  def name, it is the linkage of the type  name  to  which  the  typedef
  refers that is considered.  [Example:

          void f()
          {
              struct A { int x; };       // no linkage
              extern A a;                // ill-formed
              typedef A B;
              extern B b;                // ill-formed
          }
   --end example] This implies that names with no linkage cannot be used
  as template arguments (_temp.arg_).

8 Two names that are the same (_basic_) and that are declared in differ­
  ent  scopes  shall  denote the same object, reference, function, type,
  enumerator, template or namespace if

  --both names have external linkage or else both  names  have  internal
    linkage and are declared in the same translation unit; and

  --both names refer to members of the same namespace or to members, not
    by inheritance, of the same class; and

  --when both names denote functions, the function types  are  identical
    for purposes of overloading; and

  --when   both   names   denote   function  templates,  the  signatures
    (_temp.over.link_) are the same.

9 After all adjustments of types (during which typedefs  (_dcl.typedef_)
  are  replaced by their definitions), the types specified by all decla­
  rations of a particular external name shall be identical, except  that
  declarations  for  an array object can specify array types that differ
  by the presence or absence of a major array bound  (_dcl.array_),  and
  declarations  for  functions  with the same name can specify different
  numbers and types of parameters (_dcl.fct_).  A violation of this rule
  on type identity does not require a diagnostic.

10[Note:  linkage  to non-C++ declarations can be achieved using a link­
  age-specification (_dcl.link_).  ]

  3.6  Start and termination                               [basic.start]

  3.6.1  Main function                                [basic.start.main]

1 A program shall contain a global function called main,  which  is  the
  designated start of the program.  It is implementation-defined whether
  a program in a freestanding environment is required to define  a  main
  function.  [Note: in a freestanding environment, start-up and termina­
  tion is implementation-defined; start-up  contains  the  execution  of
  constructors  for objects of namespace scope with static storage dura­
  tion; termination contains the execution of  destructors  for  objects
  with static storage duration.  ]

2 An  implementation  shall not predefine the main function.  This func­
  tion shall not be overloaded.  It shall have a  return  type  of  type

  int,  but otherwise its type is implementation-defined.  All implemen­
  tations shall allow both of the following definitions of main:
          int main() { /* ... */ }
  and
          int main(int argc, char* argv[]) { /* ... */ }
  In the latter form argc shall be the number of arguments passed to the
  program  from the environment in which the program is run.  If argc is
  nonzero  these  arguments  shall  be  supplied  in   argv[0]   through
  argv[argc-1]  as pointers to the initial characters of null-terminated
  multibyte strings (NTMBSs) and argv[0] shall be  the  pointer  to  the
  initial  character  of a NTMBS that represents the name used to invoke
  the program or "".  The value of argc shall be nonnegative.  The value
  of  argv[argc]  shall be 0.  [Note: it is recommended that any further
  (optional) parameters be added after argv.  ]

3 The function main shall not be called  from  within  a  program.   The
  linkage  (_basic.link_)  of main is implementation-defined.  A program
  that takes the address of main, or declares it  inline  or  static  is
  ill-formed.   The name main is not otherwise reserved.  [Example: mem­
  ber functions, classes, and enumerations can be called  main,  as  can
  entities in other namespaces.  ]

4 Calling the function
          void exit(int);
  declared  in  <cstdlib> (_lib.support.start.term_) terminates the pro­
  gram without leaving the current block and  hence  without  destroying
  any  objects  with automatic storage duration (_class.dtor_).  If exit
  is called to end a program during the destruction of  an  object  with
  static storage duration, the program has undefined behavior.

5 A return statement in main has the effect of leaving the main function
  (destroying any objects with automatic storage duration)  and  calling
  exit  with  the  return value as the argument.  If control reaches the
  end of main without encountering a return  statement,  the  effect  is
  that of executing
          return 0;

  3.6.2  Initialization of non-local objects          [basic.start.init]

1 The    storage    for    objects    with   static   storage   duration
  (_basic.stc.static_) shall be zero-initialized (_dcl.init_) before any
  other    initialization   takes   place.    Objects   of   POD   types
  (_basic.types_) with static storage duration initialized with constant
  expressions  (_expr.const_)  shall  be  initialized before any dynamic
  initialization takes place.  Objects of namespace  scope  with  static
  storage  duration defined in the same translation unit and dynamically
  initialized shall be initialized in the order in which  their  defini­
  tion   appears   in  the  translation  unit.   [Note:  _dcl.init.aggr_
  describes the order in which aggregate members are  initialized.   The
  initialization of local static objects is described in _stmt.dcl_.  ]

2 An  implementation  is  permitted  to perform the initialization of an
  object of namespace scope with static storage  duration  as  a  static
  initialization  even if such initialization is not required to be done

  statically, provided that

  --the dynamic version of the initialization does not change the  value
    of  any other object of namespace scope with static storage duration
    prior to its initialization, and

  --the static version of the initialization produces the same value  in
    the  initialized object as would be produced by the dynamic initial­
    ization if all objects not required  to  be  initialized  statically
    were initialized dynamically.

  [Note:  as  a  consequence,  if  the  initialization of an object obj1
  refers to an object obj2 of namespace scope with static storage  dura­
  tion potentially requiring dynamic initialization and defined later in
  the same translation unit, it is unspecified whether the value of obj2
  used will be the value of the fully initialized obj2 (because obj2 was
  statically initialized) or will be the  value  of  obj2  merely  zero-
  initialized.  For example,
          inline double fd() { return 1.0; }
          extern double d1;
          double d2 = d1; // unspecified:
                          // may be statically initialized to 0.0 or
                          // dynamically initialized to 1.0
          double d1 = fd(); // may be initialized statically to 1.0
   --end note]

3 It   is  implementation-defined  whether  the  dynamic  initialization
  (_dcl.init_, _class.static_, _class.ctor_,  _class.expl.init_)  of  an
  object  of namespace scope with static storage duration is done before
  the first statement of main or deferred to any point in time after the
  first  statement  of  main  but  before the first use of a function or
  object defined in the same translation unit.  [Example:
          // -- File 1 --
          #include "a.h"
          #include "b.h"
          B b;
          A::A(){
                  b.Use();
          }
          // -- File 2 --
          #include "a.h"
          A a;
          // -- File 3 --
          #include "a.h"
          #include "b.h"
          extern A a;
          extern B b;
          main() {
                  a.Use();
                  b.Use();
          }
  It is implementation-defined whether  a  is  defined  before  main  is
  entered  or whether its definition is delayed until a is first used in

  main.  It is implementation-defined whether b is defined  before  main
  is  entered or whether its definition is delayed until b is first used
  in main.  In particular, if a is defined before main is entered, it is
  not  guaranteed  that  b  will be initialized before it is used by the
  initialization of a, that is, before A::A is called.  ]

4 If construction or destruction of a non-local static  object  ends  in
  throwing  an  uncaught  exception,  the  result  is  to call terminate
  (_lib.terminate_).

  3.6.3  Termination                                  [basic.start.term]

1 Destructors (_class.dtor_) for initialized objects of  static  storage
  duration  (declared  at  block scope or at namespace scope) are called
  when    returning    from    main    and     when     calling     exit
  (_lib.support.start.term_).    These  objects  are  destroyed  in  the
  reverse order of the completion of their constructors.  For an  object
  of  array  or  class type, all subobjects of that object are destroyed
  before any local object with static storage duration initialized  dur­
  ing the construction the subobjects is destroyed.

2 If  a function contains a local object of static storage duration that
  has been destroyed and the function is called during  the  destruction
  of  an  object with static storage duration, the program has undefined
  behavior if the flow of control passes through the definition  of  the
  previously destroyed local object.

3 If   a   function   is   registered   with   atexit   (see  <cstdlib>,
  _lib.support.start.term_) then following the call to exit, any objects
  with  static storage duration initialized prior to the registration of
  that function will not be destroyed until the registered  function  is
  called  from the termination process and has completed.  For an object
  with static storage duration constructed before a function  is  regis­
  tered  with  atexit,  then  following the call to exit, the registered
  function is not called until the execution of the object's  destructor
  has completed.

4 Where  a  C++  implementation  coexists  with  a C implementation, any
  actions specified by the C implementation  to  take  place  after  the
  atexit  functions  have  been  called take place after all destructors
  have been called.

5 Calling the function
          void abort();
  declared  in  <cstdlib>  terminates  the  program  without   executing
  destructors  for  objects  of automatic or static storage duration and
  without calling the functions passed to atexit().

  3.7  Storage duration                                      [basic.stc]

1 Storage duration is the property of an object that defines the minimum
  potential  lifetime of the storage containing the object.  The storage
  duration is determined by the construct used to create the object  and

  is one of the following:

  --static storage duration

  --automatic storage duration

  --dynamic storage duration

2 Static  and  automatic  storage  durations are associated with objects
  introduced by declarations (_basic.def_).  The dynamic  storage  dura­
  tion   is   associated   with   objects   created  with  operator  new
  (_expr.new_).

3 The storage class specifiers static and auto are  related  to  storage
  duration as described below.

4 References  (_dcl.ref_)  might  or might not require storage; however,
  the storage duration categories apply to references as well.

  3.7.1  Static storage duration                      [basic.stc.static]

1 All non-local objects have static storage duration.  The  storage  for
  these   objects   shall   last   for   the  duration  of  the  program
  (_basic.start.init_, _basic.start.term_).

2 If an object of  static  storage  duration  has  initialization  or  a
  destructor  with  side  effects, it shall not be eliminated even if it
  appears to be unused.

3 The keyword static can be used to declare a local variable with static
  storage  duration.   [Note: _stmt.dcl_ describes the initialization of
  local static variables; _basic.start.term_ describes  the  destruction
  of local static variables.  ]

4 The  keyword  static applied to a class data member in a class defini­
  tion gives the data member static storage duration.

  3.7.2  Automatic storage duration                     [basic.stc.auto]

1 Local objects explicitly declared auto or register or  not  explicitly
  declared  static or extern have automatic storage duration.  The stor­
  age for these objects lasts until the block in which they are  created
  exits.

2 [Note:  these  objects  are  initialized  and  destroyed  as described
  _stmt.dcl_.  ]

3 If a named automatic object has initialization or  a  destructor  with
  side  effects,  it shall not be destroyed before the end of its block,
  nor shall it be eliminated as an optimization even if it appears to be
  unused.

  3.7.3  Dynamic storage duration                    [basic.stc.dynamic]

1 Objects   can   be   created   dynamically  during  program  execution
  (_intro.execution_), using new-expressions (_expr.new_), and destroyed
  using  delete-expressions  (_expr.delete_).  A C++ implementation pro­
  vides access to, and management of, dynamic  storage  via  the  global
  allocation  functions  operator  new and operator new[] and the global
  deallocation functions operator delete and operator delete[].

2 These functions are always implicitly declared.  The library  provides
  default  definitions for them (_lib.new.delete_).  A C++ program shall
  provide at most one definition of  any  of  the  functions  ::operator
  new(size_t),   ::operator   new[](size_t),  ::operator  delete(void*),
  and/or ::operator  delete[](void*).   Any  such  function  definitions
  replace  the  default  versions.  This replacement is global and takes
  effect upon program startup (_basic.start_).  Allocation and/or  deal­
  location  functions  can  also  be  declared and defined for any class
  (_class.free_).

3 Any allocation and/or deallocation functions defined in a C++  program
  shall conform to the semantics specified in this subclause.

  3.7.3.1  Allocation functions           [basic.stc.dynamic.allocation]

1 Allocation  functions  shall be class member functions or global func­
  tions; a program is ill-formed if allocation functions are declared in
  a namespace scope other than global scope or declared static in global
  scope.  They can be overloaded, but the return type  shall  always  be
  void*   and   the   first   parameter  type  shall  always  be  size_t
  (_expr.sizeof_), an implementation-defined integral  type  defined  in
  the  standard  header  <cstddef>  (_lib.language.support_).  For these
  functions, parameters other than the first can have associated default
  arguments (_dcl.fct.default_).

2 The  function shall return the address of a block of available storage
  at least as large as the requested size.  The order,  contiguity,  and
  initial  value  of storage allocated by successive calls to an alloca­
  tion function  is  unspecified.   The  pointer  returned  is  suitably
  aligned  so  that it can be assigned to a pointer of any type and then
  used to access such an object or an array of such objects in the stor­
  age  allocated  (until the storage is explicitly deallocated by a call
  to a corresponding deallocation function).  Each such allocation shall
  yield  a  pointer  to storage (_intro.memory_) disjoint from any other
  currently allocated storage.  The pointer returned points to the start
  (lowest  byte  address)  of the allocated storage.  If the size of the
  space requested is zero, the  value  returned  shall  not  be  a  null
  pointer  value (_conv.ptr_) and shall not point to or within any other
  currently allocated storage.  The results of dereferencing  a  pointer
  returned as a request for zero size are undefined.7)
  _________________________
  7)  The intent is to have operator new() implementable by calling mal­
  loc() or calloc(), so the rules are substantially the same.  C++  dif­
  fers  from C in requiring a zero request to return a non-null pointer.

3 If an allocation function is unable to obtain an appropriate block  of
  storage,  it  can invoke  the currently installed new_handler8) and/or
  throw an exception (_except_) of class bad_alloc (_lib.bad.alloc_)  or
  a class derived from bad_alloc.

4 If  the  allocation  function  returns  the null pointer the result is
  implementation-defined.

  3.7.3.2  Deallocation functions       [basic.stc.dynamic.deallocation]

1 Deallocation functions shall be class member functions or global func­
  tions;  a program is ill-formed if deallocation functions are declared
  in a namespace scope other than global scope  or  declared  static  in
  global scope.

2 Each  deallocation  function shall return void and its first parameter
  shall be void*.  For class member  deallocation  functions,  a  second
  parameter  of  type size_t (_lib.support.types_) may be added. If both
  versions are declared in the same class, the one-parameter form is the
  usual  deallocation  function  and  the two-parameter form is used for
  placement delete (_expr.new_). If the second version is  declared  but
  not  the  first,  it is the usual deallocation function, not placement
  delete.

3 The value of the first parameter supplied to a  deallocation  function
  shall  be  a  null pointer value, or refer to storage allocated by the
  corresponding allocation function (even if  that  allocation  function
  was  called with a zero argument).  If the value of the first argument
  is a null pointer value, the call to the deallocation function has  no
  effect.   If  the  value  of  the  first  argument refers to a pointer
  already deallocated, the effect is undefined.

4 If the argument given to a deallocation function is a pointer that  is
  not  the  null  pointer  value (_conv.ptr_), the deallocation function
  will deallocate the storage referenced by the pointer and  render  the
  pointer  invalid.   The  value of a pointer that refers to deallocated
  storage is indeterminate.  The effect of using the value of a  pointer
  to deallocated storage is undefined.9)

  3.7.4  Duration of sub-objects                     [basic.stc.inherit]

1 The storage duration of member subobjects, base class  subobjects  and
  array elements is that of their complete object (_intro.object_).

  _________________________
  8)  A  program-supplied  allocation function can obtain the address of
  the currently  installed  new_handler  (_lib.new.handler_)  using  the
  set_new_handler() function (_lib.set.new.handler_).
  9)  On  some  implementations,  it  causes  a system-generated runtime
  fault.

  3.8  Object Lifetime                                      [basic.life]

1 The  lifetime  of  an object is a runtime property of the object.  The
  lifetime of an object of type T begins when:

  --storage with the proper alignment and size for type T  is  obtained,
    and

  --if  T is a class type with a non-trivial constructor (_class.ctor_),
    the constructor call has completed.

  The lifetime of an object of type T ends when:

  --if T is a class type with a non-trivial  destructor  (_class.dtor_),
    the destructor call starts, or

  --the storage which the object occupies is reused or released.

2 [Note:  the  lifetime  of an array object or of an object of POD types
  (_basic.types_) starts as soon as storage with proper size and  align­
  ment  is  obtained,  and  its lifetime ends when the storage which the
  array or object occupies is  reused  or  released.   _class.base.init_
  describes the lifetime of base and member subobjects.  ]

3 The properties ascribed to objects throughout this International Stan­
  dard apply for a given object only during  its  lifetime.   [Note:  in
  particular,  before  the  lifetime  of  an object starts and after its
  lifetime ends there are significant restrictions on  the  use  of  the
  object, as described below, in _class.base.init_ and in _class.cdtor_.
  Also, the behavior of an object  under  construction  and  destruction
  might  not be the same as the behavior of an object whose lifetime has
  started and not ended.  _class.base.init_ and  _class.cdtor_  describe
  the  behavior  of  objects  during  the  construction  and destruction
  phases.  ]

4 A program may end the lifetime of any object by  reusing  the  storage
  which  the object occupies or by explicitly calling the destructor for
  an object of a class type  with  a  non-trivial  destructor.   For  an
  object  of  a class type with a non-trivial destructor, the program is
  not required to call the  destructor  explicitly  before  the  storage
  which  the object occupies is reused or released; however, if there is
  no  explicit  call  to  the  destructor  or  if  a   delete-expression
  (_expr.delete_)  is  not  used  to release the storage, the destructor
  shall not be implicitly called and any program  that  depends  on  the
  side effects produced by the destructor has undefined behavior.

5 Before  the  lifetime  of  an object has started but after the storage
  which the object will occupy has been allocated10) or, after the life­
  time of an object has ended and while the  storage  which  the  object
  _________________________
  10) For example, before the construction of a global object of non-POD
  class type (_class.cdtor_).

  occupied still exists, any pointer that refers to the storage location
  where the object will be or was located may be used but only  in  lim­
  ited   ways.    Such   a   pointer   refers   to   allocated   storage
  (_basic.stc.dynamic.deallocation_), and using the pointer  as  if  the
  pointer  were  of  type void*, is well-defined.  Such a pointer may be
  dereferenced (to initialize a reference, for example)  but  converting
  the  resulting  lvalue to an rvalue (_conv.lval_) results in undefined
  behavior.  If the object will be or was of a class type  with  a  non-
  trivial  destructor,  and  the  pointer  is  used  as the operand of a
  delete-expression, the program has undefined behavior.  If the  object
  will  be  or  was  of  a non-POD class type, the program has undefined
  behavior if:

  --the pointer is used to access a non-static data  member  or  call  a
    non-static member function of the object, or

  --the  pointer  is implicitly converted (_conv.ptr_) to a pointer to a
    base class type, or

  --the  pointer   is   used   as   the   operand   of   a   static_cast
    (_expr.static.cast_)  (except  when  the  conversion  is to void* or
    char*)

  --the  pointer  is   used   as   the   operand   of   a   dynamic_cast
    (_expr.dynamic.cast_).  [Example:
              struct B {
                      virtual void f();
                      void mutate();
                      virtual ~B();
              };

              struct D1 : B { void f(); };
              struct D2 : B { void f(); };
              void B::mutate() {
                      new (this) D2;  // reuses storage - ends the lifetime of '*this'
                      f();            // undefined behavior
                      ... = this;     // ok, 'this' points to valid memory
              }
              void g() {
                      void* p = malloc(sizeof(D1) + sizeof(D2));
                      B* pb = new (p) D1;
                      pb->mutate();
                      &pb;            // ok: pb points to valid memory
                      void* q = pb;   // ok: pb points to valid memory
                      pb->f();        // undefined behavior, lifetime of *pb has ended
              }
     --end example]

6 Similarly,  before the lifetime of an object has started but after the
  storage which the object will occupy has been allocated or, after  the
  lifetime of an object has ended and while the storage which the object
  occupied still exists, any reference to the  original  object  may  be
  used  but  only in limited ways.  Such a reference refers to allocated
  storage (_basic.stc.dynamic.deallocation_), and using the reference as

  an  lvalue  (to  initialize  another  reference, for example) is well-
  defined.  If an lvalue-to-rvalue conversion (_conv.lval_)  is  applied
  to such a reference, the program has undefined behavior; if the origi­
  nal object will be or was of a non-POD class  type,  the  program  has
  undefined behavior if:

  --the  reference  is used to access a non-static data member or call a
    non-static member function of the object, or

  --the reference is implicitly converted (_conv.class_) to a base class
    type, or

  --the   reference   is   used   as   the   operand  of  a  static_cast
    (_expr.static.cast_) (except when the conversion is to char&), or

  --the  reference  is  used  as   the   operand   of   a   dynamic_cast
    (_expr.dynamic.cast_) or as the operand of typeid.

7 If,  after  the  lifetime of an object has ended and while the storage
  which the object occupied still exists, a new object is created at the
  storage  location  which  the original object occupied, a pointer that
  pointed to the original object will automatically  refer  to  the  new
  object  and,  once  the lifetime of the new object has started, can be
  used to manipulate the new object, if:

  --the storage for the new object exactly overlays the storage location
    which the original object occupied, and

  --the  new object is of the same type as the original object (ignoring
    the top-level cv-qualifiers), and

  --the original object was a most derived  object  (_intro.object_)  of
    type  T  and the new object is a most derived object of type T (that
    is, they are not base class subobjects).  [Example:
              struct C {
                      int i;
                      void f();
                      const C& operator=( const C& );
              };
              const C& C::operator=( const C& other)
              {
                      if ( this != &other )
                      {
                              this->~C();          // lifetime of '*this' ends
                              new (this) C(other); // new object of type C created
                              f();                 // well-defined
                      }
                      return *this;
              }
              C c1;
              C c2;
              c1 = c2; // well-defined
              c1.f();  // well-defined; c1 refers to a new object of type C
     --end example]

8 If a program ends the lifetime of an object  of  type  T  with  static
  (_basic.stc.static_)  or automatic (_basic.stc.auto_) storage duration
  and if T has a non-trivial destructor,11) the program must ensure that
  an object of the original type occupies  that  same  storage  location
  when  the implicit destructor call takes place; otherwise the behavior
  of the program is undefined.  This is true even if the block is exited
  with an exception.  [Example:
          struct B {
                  ~B();
          };
          void h() {
                  B b;
                  new (&b) T;
          } // undefined behavior at block exit
   --end example]

9 Creating  a  new  object  at  the storage location that an object with
  static or automatic storage duration occupies or, at the storage loca­
  tion  that  such  an  object  used to occupy before its lifetime ended
  results in undefined behavior.  [Example:
          struct B {
                  ~B();
          };
          const B b;
          void h() {
                  b.~B();
                  new (&b) const B; // undefined behavior
          }
   --end example]

  3.9  Types                                               [basic.types]

1 [Note: these clauses impose requirements on implementations  regarding
  the  representation of types.  There are two kinds of types: fundamen­
  tal   types   and   compound   types.     Types    describe    objects
  (_intro.object_), references (_dcl.ref_), or functions (_dcl.fct_).  ]

2 For any object type T, whether or not the object holds a  valid  value
  of  type T, the underlying bytes (_intro.memory_) making up the object
  can be copied into an array of char or unsigned char.12)

  +-------                 BEGIN BOX 8                -------+
  Change:  The  text  above  was modified to allow other mechanisms then
  just the library functions memcpy or memmove to perform  the  copying.
  Tom  Plum and Bill Plauger have pointed out that the previous restric­
  tion was too limiting and didn't follow  the  requirements  of  the  C
  _________________________
  11) that is, an object for which a destructor will be called implicit­
  ly  --  either  upon  exit from the block for an object with automatic
  storage duration or upon exit from the  program  for  an  object  with
  static storage duration.
  12) By using, for example, the library functions (_lib.headers_)  mem­
  cpy or memmove.

  memory model. Folks from the Core WG discussed this at the Tokyo meet­
  ing and were in agreement to relax the restriction.  Josée.
  +-------                  END BOX 8                 -------+

  If the content of the array of char or unsigned char  is  copied  back
  into  the  object,  the  object  shall  subsequently hold its original
  value.  [Example:
          #define N sizeof(T)
          char buf[N];
          T obj;  // obj initialized to its original value
          memcpy(buf, &obj, N);
                  // between these two calls to memcpy,
                  // obj might be modified
          memcpy(&obj, buf, N);
                  // at this point, each subobject of obj of scalar type
                  // holds its original value
   --end example]

3 For any scalar type T, if two  pointers  to  T  point  to  distinct  T
  objects obj1 and obj2, if the value of obj1 is copied into obj2, using
  the memcpy library function, obj2 shall  subsequently  hold  the  same
  value as obj1.  [Example:
          T* t1p;
          T* t2p;
                  // provided that t2p points to an initialized object ...
          memcpy(t1p, t2p, sizeof(T));
                  // at this point, every subobject of scalar type in *t1p
                  // contains the same value as the corresponding subobject in
                  // *t2p
   --end example]

4 The  object representation of an object of type T is the sequence of N
  unsigned char objects taken up by the object of type T, where N equals
  sizeof(T).   The  value representation of an object is the sequence of
  bits that hold the value of type T.  For POD types, the  value  repre­
  sentation  is  a  sequence  of  bits in the object representation that
  determines a value, which is one discrete element  of  an  implementa­
  tion-defined set of values.13)

5 Object  types  have   alignment   requirements   (_basic.fundamental_,
  _basic.compound_).   The alignment of an object type is an implementa­
  tion-defined integer value representing a number of bytes;  an  object
  is  allocated  at  an address that meets the alignment requirements of
  its object type.

6 Arrays of unknown size and classes that have  been  declared  but  not
  defined are called incomplete types.14) Also,  the  void  type  is  an
  incomplete  type  (and not an object type); it represents an empty set
  _________________________
  13) The intent is that the memory model of C++ is compatible with that
  of ISO/IEC 9899 Programming Language C.
  14)  The  size  and layout of an instance of an incomplete type is un­
  known.

  of values.  No objects shall be created to have incomplete type.   The
  term  incompletely-defined  object  type  is  a synonym for incomplete
  type; the term completely-defined object type is a  synonym  for  com­
  plete type.

7 A class type (such as "class X") might be incomplete at one point in a
  translation unit and complete later on; the type "class X" is the same
  type  at  both  points.  The declared type of an array might be incom­
  plete at one point in a translation unit and complete  later  on;  the
  array  types  at  those  two points ("array of unknown bound of T" and
  "array of N T") are different types.  However, the type of  a  pointer
  to  array  of unknown size, or of a type defined by a typedef declara­
  tion to be an array of unknown size, cannot be completed.  [Example:
          class X;             // X is an incomplete type
          extern X* xp;        // xp is a pointer to an incomplete type
          extern int arr[];    // the type of arr is incomplete
          typedef int UNKA[];  // UNKA is an incomplete type
          UNKA* arrp;          // arrp is a pointer to an incomplete type
          UNKA** arrpp;
          void foo()
          {
              xp++;             // ill-formed:  X is incomplete
              arrp++;           // ill-formed:  incomplete type
              arrpp++;          // okay: sizeof UNKA* is known
          }
          struct X { int i; };  // now X is a complete type
          int  arr[10];         // now the type of arr is complete
          X x;
          void bar()
          {
              xp = &x;          // okay; type is ``pointer to X''
              arrp = &arr;      // ill-formed: different types
              xp++;             // okay:  X is complete
              arrp++;           // ill-formed:  UNKA can't be completed
          }
   --end example]

8 [Note: _expr_, _stmt.stmt_, _dcl.dcl_ and _dcl.decl_ describe in which
  contexts incomplete types are prohibited.  ]

9 Arithmetic  types  (_basic.fundamental_),  enumeration  types, pointer
  types,  and  pointer  to  member  types  (_basic.compound_),  and  cv-
  qualified versions of these types (_basic.type.qualifier_) are collec­
  tively called scalar types.  Scalar types, POD class types, POD  union
  types  (_class_),  arrays  of  such types and cv-qualified versions of
  these  types  (_basic.type.qualifier_)  are  collectively  called  POD
  types.

10If  two  types T1 and T2 are the same type, then T1 and T2 are layout-
  compatible types.  [Note: Layout-compatible enumerations are described
  in  _dcl.enum_.   Layout-compatible  POD-structs  and  POD-unions  are
  described in _class.mem_.  ]

  3.9.1  Fundamental types                           [basic.fundamental]

1 Objects declared as characters char) shall be large  enough  to  store
  any  member of the implementation's basic character set.  If a charac­
  ter from this set is stored in a character object, its value shall  be
  equivalent  to  the integer code of that character.  It is implementa­
  tion-defined whether a char object can hold negative values.   Charac­
  ters  can  be  explicitly  declared  unsigned  or signed.  Plain char,
  signed char, and unsigned char are three distinct types.   A  char,  a
  signed char,  and  an  unsigned char occupy the same amount of storage
  and have the same alignment  requirements  (_basic.types_);  that  is,
  they  have  the  same object representation.  For character types, all
  bits of the object representation participate in the value representa­
  tion.  For  unsigned character types, all possible bit patterns of the
  value representation represent numbers. These requirements do not hold
  for  other  types.   In  any  particular  implementation, a plain char
  object can take on either the same  values  as  a  signed char  or  an
  unsigned char; which one is implementation-defined.

2 There  are  four  signed  integer  types:  "signed char", "short int",
  "int", and "long int."  In this list, each type provides at  least  as
  much  storage  as those preceding it in the list.  Plain ints have the
  natural  size  suggested  by  the  architecture   of   the   execution
  environment15) ; the other signed integer types are provided  to  meet
  special needs.

3 For  each  of  the  signed integer types, there exists a corresponding
  (but different) unsigned  integer  type:  "unsigned  char",  "unsigned
  short  int",  "unsigned  int",  and "unsigned long int," each of which
  occupies the same  amount  of  storage  and  has  the  same  alignment
  requirements  (_basic.types_)  as  the  corresponding  signed  integer
  type16) ; that is, each signed integer type has the same object repre­
  sentation as its corresponding unsigned integer type.   The  range  of
  nonnegative  values of a signed integer type is a subrange of the cor­
  responding unsigned integer type, and the value representation of  the
  same value in each type shall be the same.

4 Unsigned  integers,  declared  unsigned, shall obey the laws of arith­
  metic modulo 2n where n is the number of bits in the representation of
  that particular size of integer.17)

5 Type  wchar_t  is  a distinct type whose values can represent distinct
  codes for all members of the largest extended character set  specified
  _________________________
  15) that is, large enough to contain any value in the range of INT_MIN
  and INT_MAX, as defined in the header <climits>.
  16) See _dcl.type.simple_ regarding the correspondence  between  types
  and the sequences of type-specifiers that designate them.
  17)  This implies that unsigned arithmetic does not overflow because a
  result that cannot be represented by the  resulting  unsigned  integer
  type is reduced modulo the number that is one greater than the largest
  value that can be represented by the resulting unsigned integer  type.

  among  the  supported locales (_lib.locale_).  Type wchar_t shall have
  the same size, signedness, and alignment requirements (_intro.memory_)
  as one of the other integral types, called its underlying type.

6 Values of type bool are either true or false.18) There are no  signed,
  unsigned,  short,  or  long bool types or values.  As described below,
  bool values behave as integral types.  Values of type bool participate
  in integral promotions (_conv.prom_).

7 Types  bool,  char, wchar_t, and the signed and unsigned integer types
  are collectively called integral types.19) A synonym for integral type
  is  integer  type.  The representations of integral types shall define
  values  by  use of  a pure binary numeration system.20) [Example: this
  International Standard permits  2's  complement,  1's  complement  and
  signed magnitude representations for integral types.  ]

8 There  are three floating point types: float, double, and long double.
  The type double provides at least as much precision as float, and  the
  type  long  double provides at least as much precision as double.  The
  set of values of the type float is a subset of the set  of  values  of
  the  type  double; the set of values of the type double is a subset of
  the set of values of the type long double.  The  value  representation
  of  floating-point  is  implementation-defined.  Integral and floating
  types are collectively called arithmetic  types.   Specializations  of
  the  standard  template  numeric_limits  (_lib.support.limits_)  shall
  specify the maximum and minimum values of each arithmetic types for an
  implementation.

9 The  void  type  has an empty set of values.  It is used as the return
  type for functions that do not return a value.  The void type  is  not
  an  object  type  and  objects of type void shall not be created.  Any
  expression can be explicitly converted to type void (_expr.cast_); the
  resulting  expression  shall  be  used only as an expression statement
  (_stmt.expr_),  as  the   left   operand   of   a   comma   expression
  (_expr.comma_), or as a second or third operand of ?: (_expr.cond_).

10[Note:  Even  if the implementation defines two or more basic types to
  have the same value representation, they  are  nevertheless  different
  _________________________
  18)  Using  a bool value in ways described by this International Stan­
  dard as ``undefined,'' such as by examining the value of an uninitial­
  ized  automatic  variable,  might  cause it to behave as if is neither
  true nor false.
  19) Therefore, enumerations (_dcl.enum_) are  not  integral;  however,
  enumerations  can  be promoted to int, unsigned int, long, or unsigned
  long, as specified in _conv.prom_.
  20) A positional representation for integers that uses the binary dig­
  its  0  and  1, in which the values represented by successive bits are
  additive, begin with 1, and are multiplied by successive integral pow­
  er  of  2,  except  perhaps  for  the  bit  with the highest position.
  (Adapted from the American National Dictionary  for  Information  Pro­
  cessing Systems.)

  types.  ]

  3.9.2  Compound types                                 [basic.compound]

1 Compound  types  can  be constructed from the fundamental types in the
  following ways:

  --arrays of objects of a given type, _dcl.array_;

  --functions, which have parameters of given types and return  void  or
    references or objects of a given type, _dcl.fct_;

  --pointers  to  void or objects or functions (including static members
    of classes) of a given type, _dcl.ptr_;

  --references to objects or functions of a given type, _dcl.ref_;

  --constants, which are values of a given type, _dcl.type_;

  --classes containing a sequence of objects of various types (_class_),
    a  set  of  functions for manipulating these objects (_class.mfct_),
    and a set of restrictions on the access to these objects  and  func­
    tions, _class.access_;

  --unions, which are classes capable of containing objects of different
    types at different times, _class.union_;

  --enumerations, which comprise a set of named constant  values.   Each
    distinct   enumeration  constitutes  a  different  enumerated  type,
    _dcl.enum_;

  --pointers to non-static21) class members, which identify members of a
    given type within objects of a given class, _dcl.mptr_.

2 These methods  of  constructing  types  can  be  applied  recursively;
  restrictions  are  mentioned in _dcl.ptr_, _dcl.array_, _dcl.fct_, and
  _dcl.ref_.

3 A pointer to objects of type T is referred to as  a  "pointer  to  T."
  [Example:  a  pointer  to  an  object  of  type  int is referred to as
  "pointer to int" and a pointer to an object of class  X  is  called  a
  "pointer  to X."  ] Except for pointers to static members, text refer­
  ring to "pointers" does not apply to pointers to members.  Pointers to
  incomplete  types  are allowed although there are restrictions on what
  can be done with them (_basic.types_).  The  value  representation  of
  pointer types is implementation-defined.  Pointers to cv-qualified and
  cv-unqualified versions (_basic.type.qualifier_) of  layout-compatible
  types  shall have the same value representation and alignment require­
  ments (_basic.types_).
  _________________________
  21) Static class members are objects or  functions,  and  pointers  to
  them are ordinary pointers to objects or functions.

4 Objects of  cv-qualified  (_basic.type.qualifier_)  or  cv-unqualified
  type  void*  (pointer  to  void),  can  be used to point to objects of
  unknown type.  A void* shall be able to hold any  object  pointer.   A
  cv-qualified  or  cv-unqualified  (_basic.type.qualifier_) void* shall
  have the same representation  and  alignment  requirements  as  a  cv-
  qualified or cv-unqualified char*.

5 Except  for  pointers  to static members, text referring to "pointers"
  does not apply to pointers to members.

  3.9.3  CV-qualifiers                            [basic.type.qualifier]

1 A type mentioned in _basic.fundamental_ and _basic.compound_ is a  cv-
  unqualified    type.     Each    cv-unqualified    fundamental    type
  (_basic.fundamental_) has three corresponding cv-qualified versions of
  its type: a const-qualified version, a volatile-qualified version, and
  a   const-volatile-qualified   version.    The   term   object    type
  (_intro.object_)  includes the cv-qualifiers specified when the object
  is created.  The presence of a const specifier in a decl-specifier-seq
  declares  an  object  of  const-qualified  object type; such object is
  called a const object.  The presence of  a  volatile  specifier  in  a
  decl-specifier-seq  declares  an  object  of volatile-qualified object
  type; such object is called a volatile object.  The presence  of  both
  cv-qualifiers  in  a  decl-specifier-seq  declares an object of const-
  volatile-qualified object type; such object is called a const volatile
  object.   The  cv-qualified  or  cv-unqualified versions of a type are
  distinct types; however, they shall have the same  representation  and
  alignment requirements (_basic.types_).22)

2 A  compound  type  (_basic.compound_)  is  not cv-qualified by the cv-
  qualifiers (if any) of the type from which it is compounded.  Any  cv-
  qualifiers that appear in an array declaration apply to the array ele­
  ment type, not the array type (_dcl.array_).

3 Each non-function, non-static, non-mutable member of a const-qualified
  class  object is const-qualified, each non-function, non-static member
  of a volatile-qualified class object is volatile-qualified  and  simi­
  larly  for  members  of  a  const-volatile  class.  See  _dcl.fct_ and
  _class.this_ regarding cv-qualified function types.

4 There is a (partial) ordering on cv-qualifiers, so that a type can  be
  said  to  be  more cv-qualified than another.  Table 1 shows the rela­
  tions that constitute this ordering.

  _________________________
  22)  The  same  representation and alignment requirements are meant to
  imply interchangeability as arguments to functions, return values from
  functions, and members of unions.

                 Table 1--relations on const and volatile

                               +----------+
                  no cv-qualifier   <     const
                 no cv-qualifier   <     volatile
              no cv-qualifier  |<     const volatile
                  const     <  |  const volatile
                  volatile  <  |  const volatile
                               +----------+

5 In this International Standard, the notation cv (or cv1,  cv2,  etc.),
  used  in  the description of types, represents an arbitrary set of cv-
  qualifiers, i.e., one of {const}, {volatile},  {const,  volatile},  or
  the  empty  set.  Cv-qualifiers applied to an array type attach to the
  underlying element type, so the notation "cv T," where T is  an  array
  type,  refers to an array whose elements are so-qualified.  Such array
  types can be said to be more (or less) cv-qualified than  other  types
  based on the cv-qualification of the underlying element types.

  3.10  Lvalues and rvalues                                 [basic.lval]

1 Every expression is either an lvalue or an rvalue.

2 An  lvalue refers to an object or function.  Some rvalue expressions--
  those of class or cv-qualified class type--also refer to objects.23)

3 [Note:  some  built-in  operators  and  function  calls yield lvalues.
  [Example: if E is an expression of pointer type, then *E is an  lvalue
  expression  referring to the object or function to which E points.  As
  another example, the function
          int& f();
  yields an lvalue, so the call f() is an lvalue expression.  ] ]

4 [Note: some built-in  operators  expect  lvalue  operands.   [Example:
  built-in  assignment  operators all expect their left hand operands to
  be lvalues.  ] Other built-in operators yield rvalues, and some expect
  them.   [Example: the unary and binary + operators expect rvalue argu­
  ments and yield rvalue results.  ] The  discussion  of  each  built-in
  operator in clause _expr_ indicates whether it expects lvalue operands
  and whether it yields an lvalue.  ]

5 Constructor invocations and calls to functions that do not return ref­
  erences are always rvalues.  User defined operators are functions, and
  whether such operators expect or yield lvalues is determined by  their
  type.
  _________________________
  23) Expressions such as invocations of constructors and  of  functions
  that  return a class type refer to objects, and the implementation can
  invoke a member function upon such objects, but  the  expressions  are
  not lvalues.

6 Whenever  an  lvalue appears in a context where an rvalue is expected,
  the lvalue is converted to an rvalue; see  _conv.lval_,  _conv.array_,
  and _conv.func_.

7 The  discussion  of  reference initialization in _dcl.init.ref_ and of
  temporaries in _class.temporary_ indicates the behavior of lvalues and
  rvalues in other significant contexts.

8 Class  rvalues  can  have cv-qualified types; non-class rvalues always
  have cv-unqualified types.  Rvalues shall always have  complete  types
  or  the  void  type; in addition to these types, lvalues can also have
  incomplete types.

9 An lvalue for an object is necessary in order  to  modify  the  object
  except  that  an  rvalue  of class type can also be used to modify its
  referent under certain circumstances.   [Example:  a  member  function
  called for an object (_class.mfct_) can modify the object.  ]

10Functions cannot be modified, but pointers to functions can be modifi­
  able.

11A pointer to an incomplete type can be modifiable.  At some  point  in
  the  program when the pointed to type is complete, the object at which
  the pointer points can also be modified.

12The referent of a const-qualified expression  shall  not  be  modified
  (through  that expression), except that if it is of class type and has
  a mutable component, that component can be modified (_dcl.type.cv_).

13If an expression can be used to modify the object to which it  refers,
  the  expression is called modifiable.  A program that attempts to mod­
  ify an object through a nonmodifiable lvalue or rvalue  expression  is
  ill-formed.

14If  a program attempts to access the stored value of an object through
  an lvalue of other than one of the following  types  the  behavior  is
  undefined:

  --the dynamic type of the object,

  --a cv-qualified version of the declared type of the object,

  --a  type  that  is  the  signed or unsigned type corresponding to the
    declared type of the object,

  --a type that is the signed or unsigned type corresponding  to  a  cv-
    qualified version of the declared type of the object,

  --an  aggregate  or union type that includes one of the aforementioned
    types among its members (including, recursively, a member of a  sub­
    aggregate or contained union),

  --a  type  that  is  a  (possibly cv-qualified) base class type of the

    declared type of the object,

  --a char or unsigned char type.24)

  _________________________
  24) The intent of this list is to specify those circumstances in which
  an object may or may not be aliased.