______________________________________________________________________

  5   Expressions                                       [expr]

  ______________________________________________________________________

1 This clause defines the syntax, order of evaluation,  and  meaning  of
  expressions.   An  expression  is a sequence of operators and operands
  that specifies a computation.  An expression may result in a value and
  may cause side effects.

2 Operators  can  be  overloaded, that is, given meaning when applied to
  expressions of class type (_class_).  Uses of overloaded operators are
  transformed  into  function  calls as described in _over.oper_.  Over­
  loaded operators obey the rules for syntax specified in  this  clause,
  but the requirements of operand type, lvalue, and evaluation order are
  replaced by the rules for function call.  Relations between operators,
  such  as ++a meaning a+=1, are not guaranteed for overloaded operators
  (_over.oper_).1)

3 This clause defines the operators when applied to types for which they
  have not been overloaded.   Operator  overloading  cannot  modify  the
  rules for operators applied to types for which they are defined by the
  language itself.

4 Operators may be regrouped according to the usual  mathematical  rules
  only where the operators really are associative or commutative.  Over­
  loaded operators are never assumed to be associative  or  commutative.
  Except  where noted, the order of evaluation of operands of individual
  operators and subexpressions of individual expressions is unspecified.
  In  particular,  if  a  value  is modified twice in an expression, the
  result of the expression is unspecified except where  an  ordering  is
  guaranteed by the operators involved.  For example,
          i = v[i++];      // the value of `i' is undefined
          i=7,i++,i++;     // `i' becomes 9

5 The  handling  of overflow and divide by zero in expression evaluation
  is implementation dependent.  Most  existing  implementations  of  C++
  ignore  integer  overflows.   Treatment  of  division  by zero and all
  floating  point  exceptions  vary  among  machines,  and  is   usually
  adjustable by a library function.

6 Except  where  noted,  operands  of  types  const T,  volatile T,  T&,
  const T&, and volatile T& can be used as if they  were  of  the  plain
  type  T.  Similarly, except where noted, operands of type T* const and
  _________________________
  1) Nor is it guaranteed for type bool; the left operand of += must not
  have type bool.

  T* volatile can be used as if they were of the plain type  T*.   Simi­
  larly,  a  plain  T  can  be  used  where a volatile T or a const T is
  required.  These rules apply in  combination  so  that,  except  where
  noted,  a  T* const volatile can be used where a T* is required.  Such
  uses do not count as standard conversions when considering overloading
  resolution  (_over.match_), except when matching an object in a member
  function call against the this parameter type.

7 If an expression initially has the type  reference  to  T  (_dcl.ref_,
  _dcl.init.ref_), the type is adjusted to T prior to any further analy­
  sis, the expression designates the object or function denoted  by  the
  reference,  and  the  expression  is  an  lvalue.   A reference can be
  thought of as a name of an object.

8 User-defined conversions of class  objects  to  and  from  fundamental
  types,  pointers,  and so on, can be defined (_class.conv_).  If unam­
  biguous (_over.match_), such conversions will be applied by  the  com­
  piler  wherever a class object appears as an operand of an operator or
  as a function argument (_expr.call_).

9 Whenever an lvalue expression appears as an  operand  of  an  operator
  that   expects  an  rvalue  for  that  operand,  the  lvalue-to-rvalue
  (_conv.lval_), array-to-pointer (_conv.array_), or function-to-pointer
  (_conv.func_)  standard  conversion  will  be  applied  to convert the
  expression to an rvalue.

10Many binary operators that expect operands of  arithmetic  type  cause
  conversions  and  yield result types in a similar way.  The purpose is
  to yield a common type, which is also the type of  the  result.   This
  pattern is called the usual arithmetic conversions.

  +-------                 BEGIN BOX 1                -------+
  There  are  many places in this Clause that fail to treat enumerations
  appropriately.  Thus, for example, if e1  and  e2  are  of  enumerated
  type,  e1+e2 is some kind of integer, and what kind depends on whether
  e1 or e2 converts to long.  The definition of ``usual arithmetic  con­
  versions'' should take this into account.
  +-------                  END BOX 1                 -------+

11
  --If  either operand is of type long double, the other is converted to
    long double.

  --Otherwise, if either operand is double, the other  is  converted  to
    double.

  --Otherwise,  if  either  operand  is float, the other is converted to
    float.

  --Otherwise, the integral promotions (_conv.prom_)  are  performed  on
    both operands.

  --Then,  if  either operand is unsigned long the other is converted to

    unsigned long.

  --Otherwise, if one operand is a long int and the other unsigned  int,
    then  if a long int can represent all the values of an unsigned int,
    the unsigned int is converted to a long int; otherwise both operands
    are converted to unsigned long int.

  --Otherwise,  if  either  operand  is  long, the other is converted to
    long.

  --Otherwise, if either operand is unsigned, the other is converted  to
    unsigned.

  --Otherwise, both operands are int.

  5.1  Primary expressions                                   [expr.prim]

1 Primary  expressions  are  literals, names, and names qualified by the
  scope resolution operator ::.
          primary-expression:
                  literal
                  this
                  :: identifier
                  :: operator-function-id
                  :: qualified-id
                  ( expression )
                  id-expression

2 A literal is a primary expression.   Its  type  depends  on  its  form
  (_lex.literal_).

3 In the body of a nonstatic member function (_class.mfct_), the keyword
  this names a pointer to the object for which the function was invoked.
  The  keyword this cannot be used outside a class member function body.

  +-------                 BEGIN BOX 2                -------+
  In a  constructor  it  is  common  practice  to  allow  this  in  mem-
  initializers.
  +-------                  END BOX 2                 -------+

4 The operator :: followed by an identifier, a qualified-id, or an oper­
  ator-function-id is a primary expression.  Its type  is  specified  by
  the declaration of the identifier, name, or operator-function-id.  The
  result is the identifier, name, or operator-function-id.   The  result
  is  an  lvalue  if  the  identifier  is.   The identifier or operator-
  function-id must be of file scope.   Use  of  ::  allows  a  type,  an
  object,  a  function,  or  an enumerator to be referred to even if its
  identifier has been hidden (_basic.scope_).

5 A parenthesized expression is a  primary  expression  whose  type  and
  value  are  identical to those of the unadorned expression.  The pres­
  ence of parentheses does not  affect  whether  the  expression  is  an

  lvalue.

6 A  id-expression is a restricted form of a primary-expression that can
  appear after . and -> (_expr.ref_):
          id-expression:
                  unqualified-id
                  qualified-id

          unqualified-id:
                  identifier
                  operator-function-id
                  conversion-function-id
                  ~ class-name

  +-------                 BEGIN BOX 3                -------+
  Issue: now it's allowed to  invoke  ~int(),  but  ~class-name  doesn't
  allow for that.
  +-------                  END BOX 3                 -------+

7 An  identifier  is  an  id-expression  provided  it  has been suitably
  declared (_dcl.dcl_).   For  operator-function-ids,  see  _over.oper_.
  For  conversion-function-ids, see _class.conv.fct_.  A class-name pre­
  fixed by ~ denotes a destructor; see _class.dtor_.
          qualified-id:
                  nested-name-specifier unqualified-id

8 A nested-name-specifier that names a class (_dcl.type_) followed by ::
  and the name of a member of that class (_class.mem_), or a member of a
  base of that class (_class.derived_), is a qualified-id; its  type  is
  the  type  of the member.  The result is the member.  The result is an
  lvalue if the member is.  The class-name may be hidden  by  a  nontype
  name,  in  which  case  the class-name is still found and used.  Where
  class-name :: class-name is used, and the two class-names refer to the
  same class, this notation names the constructor (_class.ctor_).  Where
  class-name :: ~ class-name is used, the two class-names must refer  to
  the  same  class;  this  notation names the destructor (_class.dtor_).
  Multiply qualified names, such as N1::N2::N3::n, can be used to  refer
  to nested types (_class.nest_).

9 In  a  qualified-id, if the id-expression is a conversion-function-id,
  its conversion-type-id shall denote the same type in both the  context
  in  which  the  entire  qualified-id  occurs and in the context of the
  class denoted by the nested-name-specifier.  For the purpose  of  this
  evaluation,  the  name,  if  any,  of  each class is also considered a
  nested class member of that class.

  5.2  Postfix expressions                                   [expr.post]

1 Postfix expressions group left-to-right.

          postfix-expression:
                  primary-expression
                  postfix-expression [ expression ]
                  postfix-expression ( expression-listopt )
                  simple-type-specifier ( expression-listopt )
                  postfix-expression . id-expression
                  postfix-expression -> id-expression
                  postfix-expression ++
                  postfix-expression --
                  dynamic_cast < type-id > ( expression )
                  static_cast < type-id > ( expression )
                  reinterpret_cast < type-id > ( expression )
                  const_cast < type-id > ( expression )
                  typeid ( expression )
                  typeid ( type-id )
          expression-list:
                  assignment-expression
                  expression-list , assignment-expression

  5.2.1  Subscripting                                         [expr.sub]

1 A postfix expression followed by an expression in square brackets is a
  postfix  expression.   The  intuitive  meaning is that of a subscript.
  One of the expressions must have the type pointer to T and  the  other
  must  be  of enumeration or integral type.  The result is an lvalue of
  type T.  The type T must be complete.  The expression E1[E2] is  iden­
  tical   (by   definition)   to  *((E1)+(E2)).   See  _expr.unary_  and
  _expr.add_ for details of * and  +  and  _dcl.array_  for  details  of
  arrays.

  5.2.2  Function call                                       [expr.call]

1 There  are two kinds of function call: ordinary function call and mem­
  ber  function2)  (_class.mfct_)  call.   A  function call is a postfix
  expression followed by parentheses containing a possibly empty, comma-
  separated  list  of  expressions which constitute the arguments to the
  function.  For ordinary function call, the postfix expression must  be
  a  function  name,  or a pointer or reference to function.  For member
  function  call,  the  postfix   expression   must   be   an   implicit
  (_class.mfct_)  or explicit class member access (_expr.ref_) whose id-
  expression is a function member name, or a  pointer-to-member  expres­
  sion  (_expr.mptr.oper_)  selecting  a  function  member.   The  first
  expression in the postfix expression is then called the object expres­
  sion, and the call is as a member of the object pointed to or referred
  to.  If a function or member function name is used, the  name  may  be
  overloaded  (_over_),  in  which case the appropriate function will be
  selected according to the rules in _over.match_.  The function  called
  in a member function call is normally selected according to the static
  type of the object expression (see _class.derived_), but if that func­
  tion  is  virtual the function actually called will be the final over­
  rider (_class.virtual_) of the selected function in the  dynamic  type
  _________________________
  2) A static member function (_class.static_) is an ordinary  function.

  of  the  object  expression  (i.e.,  the type of the object pointed or
  referred to by the current value of the object expression).

2 The type of the function call expression is the  return  type  of  the
  statically  chosen function (i.e., ignoring the virtual keyword), even
  if the type of the function actually called is different.   This  type
  must be complete or the type void.

3 When  a  function is called, each parameter (_dcl.fct_) is initialized
  (_dcl.init.ref_, _class.copy_, _class.ctor_)  with  its  corresponding
  argument.   Standard  (_conv_) and user-defined (_class.conv_) conver­
  sions are performed.  The value  of  a  function  call  is  the  value
  returned  by  the called function except in a virtual function call if
  the return type of the final overrider is different  from  the  return
  type  of  the  statically chosen function, the value returned from the
  final overrider is converted to the return type of the statically cho­
  sen  function.   A  function  may change the values of its nonconstant
  parameters, but these changes cannot affect the values  of  the  argu­
  ments  except  where  a  parameter  is  of  a non-const reference type
  (_dcl.ref_).  Where a parameter is of reference type a temporary vari­
  able is introduced if needed (_dcl.type_, _lex.literal_, _lex.string_,
  _dcl.array_, _class.temporary_).  In addition, it is possible to  mod­
  ify the values of nonconstant objects through pointer parameters.

4 A  function  may  be  declared to accept fewer arguments (by declaring
  default arguments (_dcl.fct.default_)) or more arguments (by using the
  ellipsis,  ...   _dcl.fct_) than the number of parameters in the func­
  tion definition (_dcl.fct.def_).

5 If no declaration of the called function is accessible from the  scope
  of  the  call  the  program  is ill-formed.  This implies that, except
  where the ellipsis (...)  is used, a parameter is available  for  each
  argument.

6 Any  argument  of  type  float for which there is no parameter is con­
  verted to double before the call; any of char, short, or  a  bit-field
  type  for which there is no parameter are converted to int or unsigned
  by integral promotion (_conv.prom_).  Any argument of enumeration type
  is converted to int, unsigned, long, or unsigned long by integral pro­
  motion.  An object of a class for which no parameter  is  declared  is
  passed as a data structure.

  +-------                 BEGIN BOX 4                -------+
  To  ``pass  a parameter as a data structure'' means, roughly, that the
  parameter must be a PODS, and that otherwise  the  behavior  is  unde­
  fined.  This must be made more precise.
  +-------                  END BOX 4                 -------+

7 An  object  of  a class for which a parameter is declared is passed by
  initializing the parameter with the argument  by  a  constructor  call
  before the function is entered (_class.temporary_, _class.copy_).

8 The  order  of  evaluation of arguments is unspecified; take note that
  compilers differ.  All  side  effects  of  argument  expressions  take
  effect before the function is entered.  The order of evaluation of the
  postfix expression and the argument expression list is unspecified.

9 The function-to-pointer  standard  conversion  (_conv.func_)  is  sup­
  pressed on the postfix expression of a function call.

10Recursive calls are permitted.

11A  function call is an lvalue if and only if the result type is a ref­
  erence.

  5.2.3  Explicit type conversion (functional           [expr.type.conv]
       notation)

1 A  simple-type-specifier  (_dcl.type_)  followed  by  a  parenthesized
  expression-list constructs a value of the  specified  type  given  the
  expression list.  If the expression list specifies a single value, the
  expression is equivalent (in definedness, and if defined  in  meaning)
  to the corresponding cast expression (_expr.cast_).  If the expression
  list specifies more than a single value, the type must be a class with
  a suitably declared constructor (_dcl.init_, _class.ctor_).

2 A  simple-type-specifier  (_dcl.type_)  followed  by a (empty) pair of
  parentheses constructs a value of the specified type.  If the type  is
  a  class  with  a default constructor (_class.ctor_), that constructor
  will be called; otherwise the result is the default value given  to  a
  static object of the specified type.  See also (_expr.cast_).

  5.2.4  Class member access                                  [expr.ref]

1 A postfix expression followed by a dot .)  or an arrow ->) followed by
  an id-expression is a  postfix  expression.   The  postfix  expression
  before the dot or arrow is evaluated;3) the result of that evaluation,
  together with the id-expression, determine the result  of  the  entire
  postfix expression.

2 For  the  first  option  (dot)  the  type of the first expression (the
  object expression) shall be class object (of a  complete  type).   For
  the  second  option  (arrow)  the  type  of  the first expression (the
  pointer expression) shall be pointer to class object  (of  a  complete
  type).   The  id-expression  shall name a member of that class, except
  that an imputed destructor may be explicitly invoked  for  a  built-in
  type,  see  _class.dtor_.   Therefore,  if  E1 has the type pointer to
  class X, then the expression E1->E2 is  converted  to  the  equivalent
  form (*(E1)).E2; the remainder of this subclause will address only the
  first option (dot)4).
  _________________________
  3) This evaluation happens even if the result is unnecessary to deter­
  mine the value of the entire postfix expression, for  example  if  the
  id-expression denotes a static member.
  4) Note that if E1 has the type pointer to class X, then (*(E1)) is an
  lvalue.

3 If  the  id-expression is a qualified-id, the nested-name-specifier of
  the qualified-id may specify a namespace name or a class name.  If the
  nested-name-specifier  of the qualified-id specifies a namespace name,
  the name is looked up in the context  in  which  the  entire  postfix-
  expression occurs.  If nested-name-specifier of the qualified-id spec­
  ifies a class name, the class name is looked up as a type both in  the
  class of the object expression (or the class pointed to by the pointer
  expression) and the context in  which  the  entire  postfix-expression
  occurs.   For  the  purpose  of this type lookup, the name, if any, of
  each class is also considered a nested class  member  of  that  class.
  These  searches  shall  yield  a  single  type which might be found in
  either or both contexts.   If  the  nested-name-specifier  contains  a
  class template-id (_temp.names_), its template-arguments are evaluated
  in the context in which the entire postfix-expression occurs.

4 Similarly, if the id-expression is a conversion-function-id, its  con­
  version-type-id  shall  denote  the  same  type in both the context in
  which the entire postfix-expression occurs and in the context  of  the
  class of the object expression (or the class pointed to by the pointer
  expression).  For the purpose of this evaluation, the name, if any, of
  each class is also considered a nested class member of that class.

5 Abbreviating  object-expression.id-expression  as E1.E2, then the type
  and lvalue properties of this expression are  determined  as  follows.
  In  the remainder of this subclause, cq represents either const or the
  absence of const; vq represents either  volatile  or  the  absence  of
  volatile.

6 If  E2  is  declared  to  have  type  reference to T, then E1.E2 is an
  lvalue; the type of E1.E2 is T.  Otherwise, one of the following rules
  applies.

  --If  E2  is a static data member, and the type of E2 is cq vq T, then
    E1.E2 is an lvalue; the expression designates the  named  member  of
    the class.  The type of E1.E2 is cq vq T.

  --If  E2  is  a  (possibly overloaded) static member function, and the
    type of E2 is function of(parameter type  list)  returning  T,  then
    E1.E2  is  an  lvalue;  the  expression designates the static member
    function.  The type of E1.E2 is the same type as that of E2,  namely
    cv-qualifier function of(parameter type list) returning T.

  --If  E2 is a non-static data member, and the type of E1 is cq1 vq1 X,
    and the type of E2 is cq2 vq2 T, the expression designates the named
    member  of  the object designated by the first expression.  If E1 is
    an lvalue, then E1.E2 is an lvalue.  Let the notation vq12 stand for
    the  union of vq1 and vq2 ; that is, if vq1 or vq2 is volatile, then
    vq12 is volatile.  Similarly, let the notation cq12  stand  for  the
    union  of cq1 and cq2; that is, if cq1 or cq2 is const, then cq12 is
    const.  If E2 is declared to be a mutable member, then the  type  of
    E1.E2 is vq12 T.  If E2 is not declared to be a mutable member, then
    the type of E1.E2 is cq12 vq12 T.

  --If E2 is a (possibly overloaded) non-static member function, and the

    type  of E2 is cv-qualifier function of(parameter type list) return­
    ing T, then E1.E2 is not an lvalue.   The  expression  designates  a
    member  function (of some class X).  The expression can be used only
    as the left-hand operand of a member function  call  (_class.mfct_).
    The  member  function shall be at least as cv-qualified as the left-
    hand operand.  The type of E1.E2 is class  X's  cv-qualifier  member
    function of(parameter type list) returning T.

  --If E2 is a nested type, the expression E1.E2 is ill-formed.

  --If  E2 is a member constant, and the type of E2 is T, the expression
    E1.E2 is not an lvalue.  The type of E1.E2 is T.

7 Note that class objects can be  structures  (_class.mem_)  and  unions
  (_class.union_).  Classes are discussed in _class_.

  5.2.5  Increment and decrement                        [expr.post.incr]

1 The  value  obtained by applying a postfix ++ is (a copy of) the value
  that the operand had before applying the operator.  The operand  shall
  be  a  modifiable  lvalue.  The type of the operand shall be an arith­
  metic type or a pointer to object type.  After the  result  is  noted,
  the  value  of  the  object  is modified by adding 1 to it, unless the
  object is of type bool, in which case it is set to true (this  use  is
  deprecated).   The  type  of the result is the same as the type of the
  operand, but it is not an lvalue.  See also _expr.add_ and _expr.ass_.

2 The operand of postfix -- is decremented analogously to the postfix ++
  operator, except that the operand shall not be of type bool.

  5.2.6  Dynamic cast                                [expr.dynamic.cast]

1 The result of the expression dynamic_cast<T>(v) is of  type  T,  which
  shall  be a pointer or a reference to a complete class type or pointer
  to cv void.  The type of v shall be a complete pointer type if T is  a
  pointer,  or  a  complete  reference  type if T is a reference.  Types
  shall not be defined in a  dynamic_cast.   The  dynamic_cast  operator
  cannot cast away constness (_expr.const.cast_).

2 If  v has type T, the result is v.  If T is a pointer to class B and v
  is a pointer to class D such  that  B  is  an  unambiguous  accessible
  direct  or  indirect  base  class of D, the result is a pointer to the
  unique B sub-object of the D object pointed to by v.  Similarly, if  T
  is  a reference to class B and v is a reference to class D such that B
  is an unambiguous accessible direct or indirect base class of  D,  the
  result  is  a  reference  to the unique5) B sub-object of the D object
  referred to by v.  For example,

  _________________________
  5) The complete object pointed or referred to by v may contain other B
  objects as base classes, but these are ignored.

          struct B {};
          struct D : B {};
          void foo(D* dp)
          {
              B*  bp = dynamic_cast<B*>(dp);  // equivalent to B* bp = dp;
          }
  Otherwise  v  must  be  a  pointer  or reference to a polymorphic type
  (_class.virtual_).

3 If T is cv-qualified void* then the result is a pointer  to  the  com­
  plete  object  (_class.base.init_) pointed to by v.  Otherwise, a run-
  time check is applied to see if the object pointed or referred to by v
  can be converted to the type pointed or referred to by T.

4 The  run-time  check logically executes like this: If, in the complete
  object pointed (referred) to by v, v points (refers) to an unambiguous
  base  class  sub-object of a T object, the result is a pointer (refer­
  ence) to that T object.  Otherwise, if the type of the complete object
  has  an  unambiguous  public  base  class  of  type T, the result is a
  pointer (reference) to the T sub-object of the complete object.   Oth­
  erwise, the run-time check fails.

  +-------                 BEGIN BOX 5                -------+
  Comment  from  Bill  Gibbons:  the  original papers allowed all strict
  downcasts from accessible bases.  This wording does  not.   The  para­
  graph  can  be  fixed by changing the first instance of ``an unambigu­
  ous'' to ``a public.''
  +-------                  END BOX 5                 -------+

5 The value of a failed cast to pointer type is the null pointer, as  is
  the result of applying const_cast to a null pointer.  A failed cast to
  reference type throws bad_cast (_lib.language.support_).  For example,
          class A { virtual void f(); };
          class B { virtual void g(); };
          class D : public virtual A, private B {};
          void g()
          {
              D   d;
              B*  bp = (B*)&d;  // cast needed to break protection
              A*  ap = &d;      // public derivation, no cast needed
              D&  dr = dynamic_cast<D&>(*bp);  // succeeds
              ap = dynamic_cast<A*>(bp);       // succeeds
              bp = dynamic_cast<B*>(ap);       // fails
              ap = dynamic_cast<A*>(&dr);      // succeeds
              bp = dynamic_cast<B*>(&dr);      // fails
          }

          class E : public D , public B {};
          class F : public E, public D {}
          void h()
          {
              F   f;
              A*  ap = &f;  // okay: finds unique A
              D*  dp = dynamic_cast<D*>(ap);  // fails: ambiguous
              E*  ep = (E*)ap;  // error: cast from virtual base
              E*  ep = dynamic_cast<E*>(ap);  // succeeds
          }

  5.2.7  Type identification                               [expr.typeid]

1 The  result  of  a  typeid  expression  is  of  type  const type_info&
  (_lib.language.support_).  The value is a  reference  to  a  type_info
  object  that  represents  the  type-id  or  the type of the expression
  respectively.

2 If  the  expression   is   a   reference   to   a   polymorphic   type
  (_class.virtual_)    the    type_info    for   the   complete   object
  (_class.base.init_) referred to is the result.  Where  the  expression
  is  a  pointer  to a polymorphic type dereferenced using * or [expres­
  sion] the type_info for the complete object pointed to is the  result.
  If the pointer is zero, the expression throws the bad_typeid exception
  (_lib.language.support_).  Otherwise, if the pointer does not point to
  a valid object, the result is undefined.

3 If  the  expression is neither a pointer nor a reference to a polymor­
  phic type, the result is the type_info representing the (static)  type
  of the expression.

  5.2.8  Static cast                                  [expr.static.cast]

1 The  result  of  the expression static_cast<T>(v) is of type T.  Types
  may not be defined in a static_cast.  The conversions that may be per­
  formed explicitly using a static_cast are listed below.  No other con­
  version may be performed explicitly using a static_cast.

2 The  static_cast   operator   cannot   cast   away   constness.    See
  _expr.const.cast_.

3 Any  implicit  conversion  (including  standard  conversions and user-
  defined conversions) can be performed explicitly using static_cast.

4 A value of integral type may be explicitly converted to an enumeration
  type.   The  value  is  unchanged  if the integral value is within the
  range of the enumeration values (_dcl.enum_). Otherwise, the resulting
  enumeration value is unspecified.

5 An rvalue of type pointer to cv B, where B is a complete class, can be
  explicitly converted to an rvalue of type pointer to cv D, where D  is
  a  complete class derived (_class.derived_) from B, if a valid pointer
  conversion from pointer to cv D to pointer to cv B exists (_conv.ptr_)
  and  if B is not a virtual base class of D.  Such a cast is valid only

  if the rvalue of type pointer to cv B, points to a B that is  actually
  a  sub-object  of an object of type D; the resulting pointer points to
  the enclosing object of type D.  Otherwise (the rvalue of type pointer
  to  cv  B  does not point to a sub-object of an object of type D), the
  result of the cast is undefined.

6 Aside from this pointer  conversion  (pointer-to-base  to  pointer-to-
  derived),  the inverse of any implicit conversion (_conv_) can be per­
  formed explicitly using static_cast subject to  the  restriction  that
  the    explicit    conversion    does    not   cast   away   constness
  (_expr.const.cast_).

7 The null pointer value (_conv.ptr_) is converted to the  null  pointer
  value of the destination type.

8 An  rvalue  of  type  pointer to member of D of type cv T where D is a
  class type, may be converted to an rvalue of type pointer to member of
  B  of  type cv T, where B is a base class (_class.derived_) of D, if a
  valid pointer conversion from pointer to cv  D  to  pointer  to  cv  B
  exists  (_conv.ptr_).   The  null member pointer value (_conv.mem_) is
  converted to the null member pointer value of  the  destination  type.
  If  the  pointer  to  member  converted is not the null member pointer
  value and class B does not contain or inherit the original member, the
  result of the cast is undefined.

9 An  lvalue  expression  of type T1 may be cast to an lvalue of type T2
  using the reference cast static_cast<T2&> if  an  expression  of  type
  pointer  to  T1  may be explicitly converted to the type pointer to T2
  using a static_cast.

10Constructors (_class.ctor_) or conversion functions (_class.conv_) are
  not  called  as  the result of a cast to a reference.  Operations per­
  formed on the result of a pointer or reference cast refer to the  same
  object as the original (uncast) expression.  That is, a reference cast
  static_cast<T&>x   has   the   same   effect   as    the    conversion
  *static_cast<T*>&x  with the built-in & and * operators.  An implemen­
  tation shall not create a temporary when an lvalue  is  cast  using  a
  reference cast.  For example,
          struct B {};
          struct D : public B {};
          D d;
          // creating a temporary for the B sub-object not allowed
          ... (const B&) d ...

  +-------                 BEGIN BOX 6                -------+
  Is  it possible to cast an rvalue to an lvalue using a reference cast?
  An editorial box in this subclause used to say: [An rvalue  expression
  of type T may be explicitly converted to the type reference to const X
  if a variable of type reference to const X can be initialized with  an
  rvalue expression of type T.]  This is not true for lvalues.  i.e. the
  semantics for reference casts on lvalues are quite different from  the
  semantics  of  reference  initialization  using lvalues.  Does it make
  sense to have reference casts have different  semantics  depending  on
  whether they apply to lvalues or rvalues?

  +-------                  END BOX 6                 -------+

11The  result  of  a  reference  cast is an lvalue; the results of other
  casts are not.

12An expression may be converted to a class type (only) if an  appropri­
  ate   constructor   or   conversion   operator   has   been   declared
  (_class.conv_).

13Any  expression  may  be  explicitly  converted  to   type   cv   void
  (_basic.type.qualifier_).

  5.2.9  Reinterpret cast                        [expr.reinterpret.cast]

1 The  result  of  the  expression  reinterpret_cast<T>(v) is of type T.
  Types shall not be defined in reinterpret_cast.  Conversions that  can
  be  performed  explicitly using reinterpret_cast are listed below.  No
  other conversion may be performed explicitly using reinterpret_cast.

2 The  reinterpret_cast  operator  cannot  cast  away   constness;   see
  _expr.const.cast_.

3 The  mapping  performed by reinterpret_cast is implementation-defined;
  it may, or may not, produce a representation different from the origi­
  nal value.

4 A  pointer  can  be  explicitly  converted  to any integral type large
  enough to hold it.  The mapping  function  is  implementation-defined,
  but  is  intended  to be unsurprising to those who know the addressing
  structure of the underlying machine.

5 A value of integral type can be explicitly converted to a pointer.   A
  pointer converted to an integer of sufficient size (if any such exists
  on the implementation) and back to the same pointer type will have its
  original  value;  mappings between pointers and integers are otherwise
  implementation-defined.

6 The operand of a pointer cast may be an  rvalue  of  type  pointer  to
  incomplete  class  type.   The  target  type  of a pointer cast may be
  pointer to incomplete class type.  In such  cases,  if  there  is  any
  inheritance  relationship  between  the source and target classes, the
  behavior is undefined.

7 A pointer to a function may be explicitly converted to a pointer to  a
  function  of  a  different  type.   The  effect  of calling a function
  through a pointer to a function type that differs from the  type  used
  in  the definition of the function is undefined.  See also _conv.ptr_.

8 A pointer to an object can be explicitly converted to a pointer to  an
  object of different type.  In general, the results of this are unspec­
  ified; except that converting an rvalue of type pointer to T1  to  the
  type  pointer  to  T2  (where T1 and T2 are object types and where the
  alignment requirements of T2 are no stricter than  those  of  T1)  and

  back to its original type yields the original pointer value.

  +-------                 BEGIN BOX 7                -------+
  This  does not allow conversion of function pointers to other function
  pointer types and back.  Should it?
  +-------                  END BOX 7                 -------+

9 The null pointer value (_conv.ptr_) is converted to the  null  pointer
  value of the destination type.

10An rvalue of type pointer to member of X of type T1, may be explicitly
  converted to an rvalue of type pointer to member of Y of type  T2,  if
  T1  and  T2  are both member function types or both data member types.
  The null member pointer value (_conv.mem_) is converted  to  the  null
  member  pointer value of the destination type.  In general, the result
  of this conversion is unspecified, except that:

  --converting an rvalue of type pointer to member function to a differ­
    ent  pointer  to  member function type and back to its original type
    yields the original pointer to member value.

  --converting an rvalue of type pointer to data member of X of type  T1
    to the type pointer to data member of Y of type T2 (where the align­
    ment requirements of T2 are no stricter than those of T1)  and  back
    to its original type yields the original pointer to member value.

11Calling  a member function through a pointer to member that represents
  a function type that differs from the function type specified  on  the
  member function declaration results in undefined behavior.

12An  lvalue  expression  of type T1 may be cast to an lvalue of type T2
  using the reference reinterpret_cast<T2&> if an rvalue of type pointer
  to T1 may be explicitly converted to the type pointer to T2 with rein­
  terpret_cast.

13Constructors (_class.ctor_) or conversion functions (_class.conv_) are
  not  called  as  the result of a cast to a reference.  Operations per­
  formed on the result of a pointer or reference cast refer to the  same
  object as the original (uncast) expression.  That is, a reference cast
  reinterpret_cast<T&>x has the same effect as the conversion  *reinter­
  pret_cast<T*>&x  with  the built-in & and * operators.  An implementa­
  tion shall not creat e a temporary when an lvalue is cast using a ref­
  erence cast.

14The  result of a cast to a reference type is an lvalue; the results of
  other casts are not.

  5.2.10  Const cast                                   [expr.const.cast]

1 The result of the expression const_cast<T>(v) is of type T.  Types may
  not  be  defined  in  a const_cast.  Conversions that can be performed
  explicitly using const_cast are listed below.  No other conversion may

  be performed explicitly using constcast.

2 An  rvalue of type pointer to cv1 T may be explicitly converted to the
  type pointer to cv2 T, where T is any object type and where cv1  is  a
  different  cv-qualification  from  cv2,  using the cast const_cast<cv2
  T*>.  An lvalue of type cv1 T may be explicitly converted to an lvalue
  of type cv2 T, where T is any object type and where cv1 is a different
  cv-qualification from cv2, using the  cast  const_cast<cv2  T&>.   The
  result  of  a  pointer  or reference const_cast refers to the original
  object.

3 An rvalue of type pointer to member of X of type cv1 T may be  explic­
  itly converted to the type pointer to member of X of type cv2 T, where
  T is a data member type and where cv1 is a different  cv-qualification
  from  cv2  using  the  cast  const_cast<cv2 T X::*>.   The result of a
  pointer to member const_cast will refer to  the  same  member  as  the
  original (uncast) pointer to data member.

4 The  following rules define casting away constness.  In these rules Tn
  and Xn represent types.  For two pointer types:
            Kismin(N,M)
  casting from X1 to X2 casts away constness if, for a non-pointer  type
  T (e.g., int), there does not exist an implicit conversion from:

            Tcv1,(N-K+1)*cv1,(N-K+2)*...cv1,N*
  to

            Tcv2,(N-K+1)*cv2,(M-K+2)*...cv2,M*

5 Casting from an lvalue of type T1 to an lvalue of type T2 using a ref­
  erence cast casts away constness if a cast  from  an  rvalue  of  type
  pointer to T1 to the type pointer to T2 casts away constness.

6 Casting from an rvalue of type "pointer to data member of X of type T1
  to the type pointer to data member of Y of type T2 casts  away  const­
  ness  if  a  cast  from  an  rvalue  of type pointer to T1 to the type
  pointer to T2 casts away constness.

7 Note that these rules are not intended to  protect  constness  in  all
  cases.   For  instance,  conversions between pointers to functions are
  not covered because such conversions lead to values whose  use  causes
  undefined  behavior.  For the same reasons, conversions between point­
  ers to member functions, and in  particular,  the  conversion  from  a
  pointer  to a const member function to a pointer to a non-const member
  function, are not covered.  For multi-level pointers to data  members,
  or  multi-level mixed object and member pointers, the same rules apply
  as for multi-level object  pouinters.   That  is,  the  ``member  of''
  attribute  is  ignored  for  purposes of determining whether const has
  been cast away.

8 Depending on the type of the object, a  write  operation  through  the
  pointer,  lvalue or pointer to data member resulting from a const_cast
  that   cast-away   constness   may    produce    undefined    behavior
  (_dcl.type.cv_).

  +-------                      BEGIN BOX 8                     -------+
  This  will  need to be reworked once the memory model and object model
  are ironed out.
  +-------                       END BOX 8                      -------+

9 A null pointer value (_conv.ptr_) is converted  to  the  null  pointer
  value  of  the  destination  type.   The  null  member  pointer  value
  (_conv.mem_) is converted to the null member pointer value of the des­
  tination type.

  5.3  Unary expressions                                    [expr.unary]

1 Expressions with unary operators group right-to-left.
          unary-expression:
                  postfix-expression
                  ++  unary-expression
                  --  unary-expression
                  unary-operator cast-expression
                  sizeof unary-expression
                  sizeof ( type-id )
                  new-expression
                  delete-expression
          unary-operator: one of
                  *  &  +  -  !  ~

  5.3.1  Unary operators                                 [expr.unary.op]

1 The  unary  *  operator  means  indirection:  the expression must be a
  pointer, and the result is an lvalue referring to the object to  which
  the expression points.  If the type of the expression is pointer to T,
  the type of the result is T.

2 The result of the unary & operator is a pointer to its  operand.   The
  operand must be an lvalue, or a qualified-id.  In the first two cases,
  if the type of the expression is T, the type of the result is  pointer
  to T.  In particular, the address of an object of type cv T is pointer
  to cv T, with the same cv-qualifiers.  For example, the address of  an
  object  of type const int has type pointer to const int.  For a quali­
  fied-id, if the member is not static and of type T  in  class  C,  the
  type  of  the result is pointer to member of class C of type T.  For a
  static member of type T, the type is plain pointer to T.  Note that  a
  pointer  to  member  is only formed when an explicit & is used and its
  operand is a qualified-id not enclosed in parentheses.   For  example,
  the  expression &(qualified-id), where the qualified-id is enclosed in
  parentheses, does not form an expression of type  pointer  to  member.
  Neither  does  qualified-id,  because  there is no implicit conversion
  from the type nonstatic member function to the type pointer to  member
  function,  as  there  is  from  an lvalue of function type to the type
  pointer to function (_conv.func_).  Nor is &unqualified-id  a  pointer
  to member, even within the scope of unqualified-id's class.

  +-------                      BEGIN BOX 9                     -------+
  This  section  probably  needs  to  take  into  account  const and its

  relationship to mutable.
  +-------                       END BOX 9                      -------+

3 The address of an object of incomplete type may be taken, but only  if
  the complete type of that object does not have the address-of operator
  (operator&()) overloaded; no diagnostic is required.

4 The address of an overloaded function (_over_) can be taken only in  a
  context that uniquely determines which version of the overloaded func­
  tion is referred to (see _over.over_).  Note that  since  the  context
  may  determine  whether  the  operand  is a static or nonstatic member
  function, the context may also affect whether the expression has  type
  pointer to function or pointer to member function.

5 The operand of the unary + operator shal have arithmetic, enumeration,
  or pointer type and the result is the value of the argument.  Integral
  promotion  is performed on integral or enumeration operands.  The type
  of the result is the type of the promoted operand.

6 The operand of the unary - operator shall have arithmetic or  enumera­
  tion  type  and  the  result is the negation of its operand.  Integral
  promotion is performed on integral or enumeration operands.  The nega­
  tive of an unsigned quantity is computed by subtracting its value from
  2n, where n is the number of bits in the promoted operand.   The  type
  of the result is the type of the promoted operand.

7 The  operand  of the logical negation operator !  is converted to bool
  (_conv.bool_); its value is true if the converted operand is false and
  false otherwise.  The type of the result is bool.

8 The operand of ~ must have integral or enumeration type; the result is
  the one's complement of its operand.   Integral  promotions  are  per­
  formed.  The type of the result is the type of the promoted operand.

  5.3.2  Increment and decrement                         [expr.pre.incr]

1 The operand of prefix ++ is modified by adding 1, or set to true if it
  is bool (this use is deprecated).  The operand shall be  a  modifiable
  lvalue.   The  type  of  the  operand shall be an arithmetic type or a
  pointer to a completely-defined object type.  The  value  is  the  new
  value  of the operand; it is an lvalue.  If x is not of type bool, the
  expression ++x is equivalent to x+=1.  See the discussions of addition
  (_expr.add_)  and assignment operators (_expr.ass_) for information on
  conversions.

2 The operand of prefix -- is decremented analogously to the  prefix  ++
  operator, except that the operand shall not be of type bool.

  5.3.3  Sizeof                                            [expr.sizeof]

1 The  sizeof  operator  yields the size, in bytes, of its operand.  The
  operand is either an expression, which is not evaluated, or  a  paren­
  thesized  type-id.   The  sizeof  operator  may  not  be applied to an

  expression that has function or incomplete type, or to  the  parenthe­
  sized  name  of  such  a  type, or to an lvalue that designates a bit-
  field.  A byte is unspecified by the language except in terms  of  the
  value   of   sizeof;   sizeof(char)   is   1,   but  sizeof(bool)  and
  sizeof(wchar_t) are implementation-defined.  6)

2 When applied to a reference, the result is the size of the  referenced
  object.  When applied to a class, the result is the number of bytes in
  an object of that class including any  padding  required  for  placing
  such  objects  in  an array.  The size of any class or class object is
  greater than zero.  When applied to an array, the result is the  total
  number  of bytes in the array.  This implies that the size of an array
  of n elements is n times the size of an element.

3 The sizeof operator may be applied to a pointer to a function, but not
  to a function.

4 The  lvalue-to-rvalue  (_conv.lval_), array-to-pointer (_conv.array_),
  and function-to-pointer (_conv.func_) standard  conversions  are  sup­
  pressed on the operand of sizeof.

5 Types may not be defined in a sizeof expression.

6 The  result  is a constant of type size_t, an implementation-dependent
  unsigned integral type defined in the standard header <cstddef>.

  5.3.4  New                                                  [expr.new]

1 The new-expression  attempts  to  create  an  object  of  the  type-id
  (_dcl.name_)  to  which  it is applied.  This type shall be a complete
  object or array type (_intro.memory_, _basic.types_).
          new-expression:
                  ::opt new new-placementopt new-type-id new-initializeropt
                  ::opt new new-placementopt ( type-id ) new-initializeropt
          new-placement:
                  ( expression-list )
          new-type-id:
                  type-specifier-seq new-declaratoropt
          new-declarator:
                  * cv-qualifier-seqopt new-declaratoropt
                   ::opt nested-name-specifier * cv-qualifier-seqopt new-declaratoropt
                  direct-new-declarator
          direct-new-declarator:
                  [ expression ]
                  direct-new-declarator [ constant-expression ]
          new-initializer:
                  ( expression-listopt )
  Entities created by a new-expression  have  dynamic  storage  duration
  (_basic.stc.dynamic_).  That is, the lifetime of such an entity is not
  restricted to the scope in which it is created.  If the entity  is  an
  object,  the  new-expression  returns a pointer to the object created.
  _________________________
  6) sizeof(bool) is not required to be 1.

  If it is an array, the new-expression returns a pointer to the initial
  element of the array.

2 The  new-type  in a new-expression is the longest possible sequence of
  new-declarators.  This prevents ambiguities between declarator  opera­
  tors &, *, [], and their expression counterparts.  For example,
          new int*i;     // syntax error: parsed as `(new int*) i'
                         //               not as `(new int)*i'
  The * is the pointer declarator and not the multiplication operator.

3 Parenthese  must  not  appear in a new-type-id used as the operand for
  new.  For example,

4         new int(*[10])();       // error
  is ill-formed because the binding is
          (new int) (*[10])();    // error
  The explicitly parenthesized version of the new operator can  be  used
  to create objects of compound types (_basic.compound_).  For example,
          new (int (*[10])());
  allocates an array of 10 pointers to functions (taking no argument and
  returning int).

5 The type-specifier-seq shall not contain const, volatile, class decla­
  rations, or enumeration declarations.

6 When  the  allocated  object  is  an  array  (that is, the direct-new-
  declarator syntax is used or the new-type-id  or  type-id  denotes  an
  array  type),  the new-expression yields a pointer to the initial ele­
  ment (if any) of the array.  Thus, both new int and new int[10] return
  an int* and the type of new int[i][10] is int (*)[10].

7 Every constant-expression in a direct-new-declarator shall be an inte­
  gral constant  expression  (_expr.const_)  with  a  strictly  positive
  value.  The expression in a direct-new-declarator shall be of integral
  type (_basic.fundamental_) with a non-negative value.  For example, if
  n  is  a  variable  of  type  int, then new float[n][5] is well-formed
  (because  n  is  the  expression  of  a  direct-new-declarator),   but
  new float[5][n]   is   ill-formed   (because  n  is  not  a  constant-
  expression).  If n is negative, the effect of new float[n][5] is unde­
  fined.

8 When  the  value of the expression in a direct-new-declarator is zero,
  an array with no elements is allocated.  The pointer returned  by  the
  new-expression  will  be non-null and distinct from the pointer to any
  other object.

9 Storage for the object created by a new-expression  is  obtained  from
  the  appropriate allocation function (_basic.stc.dynamic.allocation_).
  When the allocation function is called, the  first  argument  will  be
  amount  of  space  requested (which may be larger than the size of the
  object being created only if that object is an array).

10An implementation provides default definitions of the  global  alloca­
  tion   functions  operator new()  for  non-arrays  (_lib.op.new_)  and

  operator new[]() for arrays (_lib.op.new.array_).  A C++  program  may
  provide     alternative     definitions     of     these     functions
  (_lib.alternate.definitions.for.functions_),   and/or   class-specific
  versions (_class.free_).

11The new-placement syntax can be used to supply additional arguments to
  an allocation function.  Overloading resolution is done by  assembling
  an  argument  list from the amount of space requested (the first argu­
  ment) and the expressions  in  the  new-placement  part  of  the  new-
  expression, if used (the second and succeeding arguments).

12For example:

  --new T results in a call of operator new(sizeof(T)),

  --new(2,f) T results in a call of operator new(sizeof(T),2,f),

  --new T[5] results in a call of operator new[](x), and

  --new(2,f) T[5] results in a call of operator new[](y,2,f).

13The  return  value  from the allocation function, if non-null, will be
  assumed to point to a block of appropriately aligned available storage
  of  the  requested  size, and the object will be created in that block
  (but not necessarily at the beginning of the block, if the  object  is
  an array).

14If  a  class  has  one  or  more  constructors  (_class.ctor_), a new-
  expression for that class calls one of them to initialize the  object.
  An  object of a class can be created by new only if suitable arguments
  are provided to the class' constructors, or if the class has a default
  constructor (_basic.def_).7) If the class does not have a default con­
  structor, suitable arguments (_over.match_) must be provided in a new-
  initializer.  If there is no  constructor  and  a  new-initializer  is
  used,  it must be of the form (expression) or ().  If an expression is
  present it will be used to initialize the object; if not,  or  a  new-
  initializer is not used, the object will start out with an unspecified
  value.

15No initializers can be specified for arrays.  Arrays of objects  of  a
  class  can  be  created  by  a  new-expression only if the class has a
  default constructor.8) In that case, the default constructor  will  be
  called  for each element of the array, in order of increasing address.

16Access and ambiguity control are done for both the allocation function
  and the constructor (_class.ctor_, _class.free_).

17The  allocation  function  may  indicate  failure by throwing an alloc
  exception (_except_, _lib.alloc_).  In this case no initialization  is
  _________________________
  7)  This  means  that  struct  s{};  s*  ps = new s; is allowed on the
  grounds that class s has an implicitly declared constructor.
  8) PODS structs have an implicitly-declared default constructor.

  done.

18If the constructor throws an exception and the new-expression does not
  contain   a   new-placement,   then    the    deallocation    function
  (_basic.stc.dynamic.deallocation_,  _class.free_)  is used to free the
  memory in which the object was  being  constructed,  after  which  the
  exception continues to propagate in the context of the new-expression.

19The way the object was allocated determines how it is freed: if it  is
  allocated  by  ::new,  then  it  is freed by ::delete, and if it is an
  array, it is freed by delete[] or ::delete[] as appropriate.

  +-------                     BEGIN BOX 10                     -------+
  This is a correction to San Diego resolution 3.5, which  on  its  face
  seems  to  require  that  whether  to  use  delete or delete[] must be
  decided purely on syntactic grounds.  I believe the intent of the com­
  mittee  was  to  make the form of delete correspond to the form of the
  corresponding new.
  +-------                      END BOX 10                      -------+

20Whether the allocation function is called before evaluating  the  con­
  structor  arguments,  after  evaluating  the constructor arguments but
  before entering the constructor,  or  by  the  constructor  itself  is
  unspecified.   It  is also unspecified whether the arguments to a con­
  structor are evaluated if the allocation  function  returns  the  null
  pointer or throws an exception.

  5.3.5  Delete                                            [expr.delete]

1 The    delete-expression   operator   destroys   a   complete   object
  (_intro.memory_) or array created by a new-expression.
          delete-expression:
                  ::opt delete cast-expression
                  ::opt delete [ ] cast-expression
  The first alternative is for non-array objects, and the second is  for
  arrays.  The result has type void.

2 In  either  alternative,  if the value of the operand of delete is the
  null pointer the operation has no effect.   Otherwise,  in  the  first
  alternative  (delete object), the value of the operand of delete shall
  be a pointer to a non-array object created by a new-expression without
  a   new-placement   specification,   or  a  pointer  to  a  sub-object
  (_intro.memory_)  representing  a  base  class  of  such   an   object
  (_class.derived_).

  +-------                     BEGIN BOX 11                     -------+
  Issue: ... or a class with an unambiguous conversion to such a pointer
  type ...
  +-------                      END BOX 11                      -------+

  In the second alternative (delete array), the value of the operand  of
  delete  shall  be  a  pointer  to an array created by a new-expression
  without a new-placement specification.

3 In the first alternative (delete object), if the static  type  of  the
  operand  is different from its dynamic type, the static type must have
  a virtual destructor or the result is undefined.  In the second alter­
  native  (delete array) if the dynamic type of the object to be deleted
  is a class that has a destructor and its static type is different from
  its dynamic type, the result is undefined.

  +-------                     BEGIN BOX 12                     -------+
  This  should  probably  be  tightened  to  require that the static and
  dynamic types match, period.
  +-------                      END BOX 12                      -------+

4 The deletion of an object may change its  value.   If  the  expression
  denoting the object in a delete-expression is a modifiable lvalue, any
  attempt  to  access  its  value  after  the  deletion   is   undefined
  (_basic.stc.dynamic.deallocation_).

5 A  C++  program  that  applies delete to a pointer to constant is ill-
  formed (_intro.compliance_, _intro.execution_).

6 If the class of the object being deleted is incomplete at the point of
  deletion and the class has a destructor or an allocation function or a
  deallocation function, the result is undefined.

7 The delete-expression will invoke the  destructor  (if  any)  for  the
  object  or the elements of the array being deleted.  In the case of an
  array, the elements will be destroyed in order of  decreasing  address
  (that is, in reverse order of construction).

8 To  free  the  storage  pointed  to, the delete-expression will call a
  deallocation function (_basic.stc.dynamic.deallocation_).

9 An implementation provides default definitions of the global dealloca­
  tion  functions operator delete() for non-arrays (_lib.op.delete_) and
  operator delete[]() for arrays (_lib.op.delete.array_).  A C++ program
  may    provide    alternative    definitions    of   these   functions
  (_lib.alternate.definitions.for.functions_),   and/or   class-specific
  versions (_class.free_).

10Access  and ambiguity control are done for both the deallocation func­
  tion and the destructor (_class.dtor_, _class.free_).

  5.4  Explicit type conversion (cast notation)              [expr.cast]

1 The result of the expression (T) cast-expression is  of  type  T.   An
  explicit  type  conversion  can be expressed using functional notation
  (_expr.type.conv_),  a   type   conversion   operator   (dynamic_cast,
  static_cast, reinterpret_cast, const_cast), or the cast notation.
          cast-expression:
                  unary-expression
                  ( type-id ) cast-expression

2 Types may not be defined in casts.

3 Any  type conversion not mentioned below and not explicitly defined by
  the user (_class.conv_) is ill-formed.

4 The conversions performed by static_cast  (_expr.static.cast_),  rein­
  terpret_cast           (_expr.reinterpret.cast_),           const_cast
  (_expr.const.cast_), or any sequence thereof, may be  performed  using
  the  cast  notation  of  explicit  type conversion.  The same semantic
  restrictions and behaviors apply.

5 In addition to those conversions, a pointer to an object of a  derived
  class  (_class.derived_)  may  be explicitly converted to a pointer to
  any of its  base  classes  regardless  of  accessibility  restrictions
  (_class.access.base_),   provided   the   conversion   is  unambiguous
  (_class.member.lookup_).  The resulting pointer will refer to the con­
  tained object of the base class.

  5.5  Pointer-to-member operators                      [expr.mptr.oper]

1 The pointer-to-member operators ->* and .*  group left-to-right.
          pm-expression:
                  cast-expression
                  pm-expression .* cast-expression
                  pm-expression ->* cast-expression

2 The  binary  operator  .*   binds its second operand, which must be of
  type pointer to member of T to its first operand,  which  must  be  of
  class T or of a class of which T is an unambiguous and accessible base
  class.  The result is an object or a function of the type specified by
  the second operand.

3 The  binary  operator  ->*  binds its second operand, which must be of
  type pointer to member of T to its first operand,  which  must  be  of
  type  pointer  to T or pointer to a class of which T is an unambiguous
  and accessible base class.  The result is an object or a  function  of
  the type specified by the second operand.

4 If  the  result  of  .*  or ->* is a function, then that result can be
  used only as the operand for the function call operator ().  For exam­
  ple,
          (ptr_to_obj->*ptr_to_mfct)(10);
  calls  the  member  function  denoted  by  ptr_to_mfct  for the object
  pointed to by ptr_to_obj.  The result of a .*  expression is an lvalue
  only  if  its  first  operand is an lvalue and its second operand is a
  pointer to data member.  The result of an ->* expression is an  lvalue
  only if its second operand is a pointer to data member.  If the second
  operand is the null pointer to member value (_conv.mem_),  the  result
  is undefined.

  5.6  Multiplicative operators                               [expr.mul]

1 The multiplicative operators *, /, and % group left-to-right.
          multiplicative-expression:
                  pm-expression
                  multiplicative-expression * pm-expression
                  multiplicative-expression / pm-expression
                  multiplicative-expression % pm-expression

2 The  operands  of * and / must have arithmetic type; the operands of %
  must  have  integral   type.    The   usual   arithmetic   conversions
  (_conv.arith_) are performed on the operands and determine the type of
  the result.

3 The binary * operator indicates multiplication.

4 The binary / operator yields the quotient, and the binary  %  operator
  yields  the remainder from the division of the first expression by the
  second.  If the second operand of / or % is zero the result  is  unde­
  fined;  otherwise  (a/b)*b  + a%b is equal to a.  If both operands are
  nonnegative then the remainder is nonnegative; if not, the sign of the
  remainder is implementation dependent.

  5.7  Additive operators                                     [expr.add]

1 The  additive operators + and - group left-to-right.  The usual arith­
  metic conversions (_conv.arith_) are performed for operands of  arith­
  metic type.
          additive-expression:
                  multiplicative-expression
                  additive-expression + multiplicative-expression
                  additive-expression - multiplicative-expression
  For  addition, either both operands shall have arithmetic type, or one
  operand shall be a pointer to a completely defined object type and the
  other shall have integral type.

2 For subtraction, one of the following shall hold:

  --both operands have arithmetic type;

  --both  operands  are pointers to qualified or unqualified versions of
    the same completely defined object type; or

  --the left operand is a pointer to a completely  defined  object  type
    and the right operand has integral type.

3 If  both  operands  have arithmetic type, the usual arithmetic conver­
  sions are performed on them.  The result of the binary +  operator  is
  the  sum  of the operands.  The result of the binary - operator is the
  difference resulting from the subtraction of the second  operand  from
  the first.

4 For  the  purposes  of these operators, a pointer to a nonarray object
  behaves the same as a pointer to the first  element  of  an  array  of

  length one with the type of the object as its element type.

5 When  an  expression  that has integral type is added to or subtracted
  from a pointer, the result has the type of the  pointer  operand.   If
  the  pointer  operand points to an element of an array object, and the
  array is large enough, the result points to an element offset from the
  original  element  such  that  the difference of the subscripts of the
  resulting and original array elements equals the integral  expression.
  In  other  words, if the expression P points to the i-th element of an
  array object, the expressions (P)+N (equivalently,  N+(P))  and  (P)-N
  (where  N has the value n) point to, respectively, the i+n-th and i-n-
  th elements of the array object, provided they  exist.   Moreover,  if
  the  expression  P  points to the last element of an array object, the
  expression (P)+1 points one past the last element of the array object,
  and  if  the expression Q points one past the last element of an array
  object, the expression (Q)-1 points to the last element of  the  array
  object.   If both the pointer operand and the result point to elements
  of the same array object, or one past the last element  of  the  array
  object,  the  evaluation shall not produce an overflow; otherwise, the
  behavior is undefined.  If the result is used as  an  operand  of  the
  unary  *  operator,  the behavior is undefined unless both the pointer
  operand and the result point to elements of the same array object,  or
  the  pointer  operand  points  one  past  the last element of an array
  object and the result points to an element of the same array object.

6 When two pointers to elements of the same array object are subtracted,
  the  result  is the difference of the subscripts of the two array ele­
  ments.  The type of the result  is  an  implementation-defined  signed
  integral  type;  this  type  shall be the same type that is defined as
  ptrdiff_t in the <cstddef> header (_lib.language.support_).   As  with
  any other arithmetic overflow, if the result does not fit in the space
  provided, the behavior is undefined.  In other words, if  the  expres­
  sions P and Q point to, respectively, the i-th and j-th elements of an
  array object, the expression (P)-(Q) has the value  i-j  provided  the
  value  fits  in an object of type ptrdiff_t.  Moreover, if the expres­
  sion P points either to an element of an array object or one past  the
  last  element  of  an array object, and the expression Q points to the
  last element of the same array object, the expression ((Q)+1)-(P)  has
  the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and has the value
  zero if the expression P points one past the last element of the array
  object,  even though the expression (Q)+1 does not point to an element
  of the array object.  Unless both pointers point to  elements  of  the
  same  array  object, or one past the last element of the array object,
  the behavior is undefined.9)
  _________________________
  9) Another way to approach pointer arithmetic is first to convert  the
  pointer(s)  to  character  pointer(s): In this scheme the integral ex­
  pression added to or subtracted from the converted  pointer  is  first
  multiplied  by  the  size of the object originally pointed to, and the
  resulting pointer is converted back to the original type.  For pointer
  subtraction, the result of the difference between the character point­
  ers is similarly divided by the size of the object originally  pointed
  to.

  5.8  Shift operators                                      [expr.shift]

1 The shift operators << and >> group left-to-right.
          shift-expression:
                  additive-expression
                  shift-expression << additive-expression
                  shift-expression >> additive-expression
  The operands must be of integral type and integral promotions are per­
  formed.   The type of the result is that of the promoted left operand.
  The result is undefined if the right operand is negative,  or  greater
  than or equal to the length in bits of the promoted left operand.  The
  value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted E2
  bits;  vacated  bits  are  zero-filled.   The  value of E1 >> E2 is E1
  right-shifted E2 bit positions.  The right shift is guaranteed  to  be
  logical (zero-fill) if E1 has an unsigned type or if it has a nonnega­
  tive value; otherwise the result is implementation dependent.

  5.9  Relational operators                                   [expr.rel]

1 The relational operators group left-to-right, but  this  fact  is  not
  very useful; a<b<c means (a<b)<c and not (a<b)&&(b<c).
          relational-expression:
                  shift-expression
                  relational-expression < shift-expression
                  relational-expression > shift-expression
                  relational-expression <= shift-expression
                  relational-expression >= shift-expression
  The  operands  must  have arithmetic or pointer type.  The operators <
  (less than), > (greater than), <= (less than  or  equal  to),  and  >=
  (greater  than  or equal to) all yield false or true.  The type of the
  result is bool.

2 The usual arithmetic conversions are performed on arithmetic operands.
  Pointer conversions are performed on pointer operands to bring them to
  the same type, which must be a qualified or unqualified version of the
  type  of  one  of  the operands.  This implies that any pointer may be
  compared to an integral constant expression evaluating to zero and any
  pointer  can be compared to a pointer of qualified or unqualified type
  void* (in the latter case the pointer is first  converted  to  void*).
  Pointers  to objects or functions of the same type (after pointer con­
  versions) may be compared; the result depends on  the  relative  posi­
  tions of the pointed-to objects or functions in the address space.

3 If two pointers of the same type point to the same object or function,
  or both point one past the end of the same array, or  are  both  null,
  they compare equal.  If two pointers of the same type point to differ­
  ent objects or functions, or only one of them is  null,  they  compare
  unequal.   If two pointers point to nonstatic data members of the same
  _________________________
7 When viewed in this way, an implementation need only provide one extra
  byte (which may overlap another object in the program) just after  the
  end  of  the  object in order to satisfy the one past the last element
  requirements.

  object, the pointer to the later declared member compares higher  pro­
  vided  the  two  members  not  separated  by an access-specifier label
  (_class.access.spec_) and provided their class is not a union.  If two
  pointers point to nonstatic members of the same object separated by an
  access-specifier label (_class.access.spec_) the  result  is  unspeci­
  fied.   If  two pointers point to data members of the same union, they
  compare equal (after conversion  to  void*,  if  necessary).   If  two
  pointers  point to elements of the same array or one beyond the end of
  the array, the pointer to the object with the  higher  subscript  com­
  pares higher.  Other pointer comparisons are implementation-defined.

  5.10  Equality operators                                     [expr.eq]

1         equality-expression:
                  relational-expression
                  equality-expression == relational-expression
                  equality-expression != relational-expression
  The  ==  (equal  to) and the != (not equal to) operators have the same
  semantic restrictions, conversions, and result type as the  relational
  operators  except  for  their lower precedence and truth-value result.
  (Thus a<b == c<d is true whenever a<b and c<d  have  the  same  truth-
  value.)

2 In  addition,  pointers  to  members of the same type may be compared.
  Pointer to member conversions (_conv.mem_) are performed.   A  pointer
  to  member  may  be  compared  to an integral constant expression that
  evaluates to zero.  If one operand is a pointer to  a  virtual  member
  function  and  the  other is not the null pointer to member value, the
  result is unspecified.

  5.11  Bitwise AND operator                              [expr.bit.and]

1         and-expression:
                  equality-expression
                  and-expression & equality-expression
  The usual arithmetic conversions are performed; the result is the bit­
  wise  function of the operands.  The operator applies only to integral
  operands.

  5.12  Bitwise exclusive OR operator                         [expr.xor]

1         exclusive-or-expression:
                  and-expression
                  exclusive-or-expression ^ and-expression
  The usual arithmetic conversions are performed; the result is the bit­
  wise exclusive function of the operands.  The operator applies only to
  integral operands.

  5.13  Bitwise inclusive OR operator                          [expr.or]

1         inclusive-or-expression:
                  exclusive-or-expression
                  inclusive-or-expression | exclusive-or-expression
  The usual arithmetic conversions are  performed;  the  result  is  the

  bitwise inclusive function of its operands.  The operator applies only
  to integral operands.

  5.14  Logical AND operator                              [expr.log.and]

1         logical-and-expression:
                  inclusive-or-expression
                  logical-and-expression && inclusive-or-expression
  The && operator groups left-to-right.  The operands are both converted
  to type bool (_conv.bool_).  The result is true if both  operands  are
  true and false otherwise.  Unlike &, && guarantees left-to-right eval­
  uation: the second operand is not evaluated if the  first  operand  is
  false.

2 The result is a bool.  All side effects of the first expression except
  for destruction of temporaries (_class.temporary_) happen  before  the
  second expression is evaluated.

  5.15  Logical OR operator                                [expr.log.or]

1         logical-or-expression:
                  logical-and-expression
                  logical-or-expression || logical-and-expression
  The || operator groups left-to-right.  The operands are both converted
  to bool (_conv.bool_).  It returns true if either of its  operands  is
  true,  and  false  otherwise.   Unlike  |, || guarantees left-to-right
  evaluation; moreover, the second operand is not evaluated if the first
  operand evaluates to true.

2 The result is a bool.  All side effects of the first expression except
  for destruction of temporaries (_class.temporary_) happen  before  the
  second expression is evaluated.

  5.16  Conditional operator                                 [expr.cond]

1         conditional-expression:
                  logical-or-expression
                  logical-or-expression ? expression : assignment-expression
  Conditional  expressions group right-to-left.  The first expression is
  converted to bool (_conv.bool_).  It is evaluated and if it  is  true,
  the  result  of  the conditional expression is the value of the second
  expression, otherwise that of the third expression.  All side  effects
  of   the  first  expression  except  for  destruction  of  temporaries
  (_class.temporary_) happen before the second or  third  expression  is
  evaluated.

2 If  either  the  second  or  third  expression  is  a throw-expression
  (_except.throw_), the result is of the type of the other.

3 If both the second and the third expressions are of  arithmetic  type,
  then  if  they are of the same type the result is of that type; other­
  wise the usual arithmetic conversions are performed to bring them to a
  common  type.  Otherwise, if both the second and the third expressions
  are either a pointer or an integral constant expression that evaluates

  to  zero, pointer conversions (_conv.ptr_) are performed to bring them
  to a common type which must be a qualified or unqualified  version  of
  the  type of either the second or the third expression.  Otherwise, if
  both the second and the third expressions are either a pointer to mem­
  ber or an integral constant expression that evaluates to zero, pointer
  to member conversions (_conv.mem_) are performed to bring  them  to  a
  common type10) which must be a qualified or unqualified version of the
  type of either the second or the third expression.  Otherwise, if both
  the second and the third expressions  are  lvalues  of  related  class
  types, they are converted to a common type as if by a cast to a refer­
  ence to the common type (_expr.static.cast_).  Otherwise, if both  the
  second  and  the third expressions are of the same class T, the common
  type is T.  Otherwise, if both the second and  the  third  expressions
  have  type cv void, the common type is cv void.  Otherwise the expres­
  sion is ill formed.  The result has the common type; only one  of  the
  second and third expressions is evaluated.  The result is an lvalue if
  the second and the third operands are of the same type  and  both  are
  lvalues.

  5.17  Assignment operators                                  [expr.ass]

1 There  are  several assignment operators, all of which group right-to-
  left.  All require a modifiable lvalue as their left operand, and  the
  type  of  an  assignment  expression is that of its left operand.  The
  result of the assignment operation is the value  stored  in  the  left
  operand after the assignment has taken place; the result is an lvalue.
          assignment-expression:
                  conditional-expression
                  unary-expression assignment-operator assignment-expression
                  throw-expression
          assignment-operator: one of
                  =  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=

2 In simple assignment (=), the value of the expression replaces that of
  the object referred to by the left operand.

3 If  the left operand is not of class type, the expression is converted
  to the unqualified type of the left operand using standard conversions
  (_conv_) and/or user-defined conversions (_class.conv_), as necessary.

4 Assignment to objects of a class (_class_) X is defined by  the  func­
  tion   X::operator=()   (_over.ass_).   Unless  the  user  defines  an
  X::operator=(),  the  default   version   is   used   for   assignment
  (_class.copy_).  This implies that an object of a class derived from X
  (directly   or   indirectly)   by   unambiguous   public    derivation
  (_class.derived_) can be assigned to an X.

5 For  class  objects, assignment is not in general the same as initial­
  ization (_dcl.init_, _class.ctor_, _class.init_, _class.copy_).

  _________________________
  10)  This is one instance in which the composite type, as described in
  the C Standard, is still employed in C++.

6 When the left operand of an assignment operator denotes a reference to
  T, the operation assigns to the object of type T denoted by the refer­
  ence.

7 The behavior of an expression of the form E1 op= E2 is  equivalent  to
  E1=E1 op  E2 except that E1 is evaluated only once.  E1 shall not have
  bool type.  In += and -=, E1 can be a pointer to a  possibly-qualified
  completely  defined  object type, in which case E2 shall have integral
  type and is converted as explained in _expr.add_; In all other  cases,
  E1 and E2 shall have arithmetic type.

8 See _except.throw_ for throw expressions.

  5.18  Comma operator                                      [expr.comma]

1 The comma operator groups left-to-right.
          expression:
                  assignment-expression
                  expression , assignment-expression
  A  pair of expressions separated by a comma is evaluated left-to-right
  and the value of the left expression is discarded.  All  side  effects
  of  the  left  expression  are  performed before the evaluation of the
  right expression.  The type and value of the result are the  type  and
  value  of  the  right  operand;  the  result is an lvalue if its right
  operand is.

2 In contexts where comma is given a special meaning,  for  example,  in
  lists  of arguments to functions (_expr.call_) and lists of initializ­
  ers (_dcl.init_), the comma operator as described in this  clause  can
  appear only in parentheses; for example,
          f(a, (t=3, t+2), c);
  has three arguments, the second of which has the value 5.

  5.19  Constant expressions                                [expr.const]

1 In  several places, C++ requires expressions that evaluate to an inte­
  gral constant: as array  bounds  (_dcl.array_),  as  case  expressions
  (_stmt.switch_), as bit-field lengths (_class.bit_), and as enumerator
  initializers (_dcl.enum_).
          constant-expression:
                  conditional-expression
  An   integral   constant-expression   can   involve   only    literals
  (_lex.literal_),  enumerators, const values of integral types initial­
  ized with constant expressions (_dcl.init_), and  sizeof  expressions.
  Floating  constants (_lex.fcon_) must be cast to integral types.  Only
  type conversions to integral types may be used.  In particular, except
  in  sizeof  expressions, functions, class objects, pointers, or refer­
  ences cannot be used, and assignment, increment, decrement,  function-
  call, or comma operators cannot be used.

2 Other  expressions  are  considered  constant-expressions only for the
  purpose     of     non-local     static     object      initialization
  (_basic.start.init_).  Such constant expressions shall evaluate to one
  of the following:

    --a null pointer constant (_conv.ptr_),

    --a null member pointer value (_conv.mem_),

    --an arithmetic constant expression,

    --an address constant,

    --an address constant for an object type plus or minus  an  integral
      constant expression, or

    --a pointer to member constant expression.

3 An arithmetic constant expression shall have arithmetic type and shall
  only have operands that are integer constants  (_lex.icon_),  floating
  constants  (_lex.fcon_), enumerators, character constants (_lex.ccon_)
  and sizeof expressions (_expr.sizeof_).  Casts operators in an  arith­
  metic  constant  expression  shall  only  convert  arithmetic types to
  arithmetic types, except as part of an operand to the sizeof operator.

4 An address constant is a pointer to an lvalue designating an object of
  static storage duration or a function.  The pointer shall  be  created
  explicitly, using the unary & operator, or implicitly using an expres­
  sion of array (_conv.array_) or function (_conv.func_) type.  The sub­
  scripting operator [] and the class member access .  and -> operators,
  the & and * unary operators, and pointer casts (except  dynamic_casts,
  _expr.dynamic.cast_)  may  be  used in the creation of an address con­
  stant, but the value of an object shall not be accessed by the use  of
  these operators.  Function calls cannot be used in an address constant
  expression, even if the function is inline and has a reference  return
  type.

5 A  pointer  to  member  constant expression shall be created using the
  unary & operator applied to a qualified-id operand  (_expr.unary.op_).