      ______________________________________________________________________

      Annex 0 (informative)

      Compatibility                                                   [diff]

      ______________________________________________________________________

    1 This Annex summarizes the evolution of C++ since the first edition  of
      The  C++  Programming  Language and explains in detail the differences
      between C++ and C.  Because the C language as described by this Inter-
      national  Standard differs from the dialects of Classic C used up till
      now, we discuss the differences between C++ and ISO C as well  as  the
      differences between C++ and Classic C.

    2 C++  is based on C (K&R78) and adopts most of the changes specified by
      the ISO C standard.  Converting programs among C++, K&R C, and  ISO  C
      may  be subject to vicissitudes of expression evaluation.  All differ-
      ences between C++ and ISO C can be  diagnosed  by  an  implementation.
      With  the  exceptions listed in this Annex, programs that are both C++
      and ISO C have the same meaning in both languages.

      1.1  Extensions                                               [diff.c]

    1 This subclause summarizes the major extensions to C provided by C++.

      1.1.1  C++ features available in 1985                     [diff.early]

    1 This subclause summarizes the extensions to C provided by C++  in  the
      1985 version of its manual:

    2 The types of function parameters can be specified (_dcl.fct_) and will
      be  checked  (_expr.call_).   Type  conversions  will   be   performed
      (_expr.call_).  This is also in ISO C.

    3 Single-precision  floating  point  arithmetic  may  be  used for float
      expressions; _basic.fundamental_ and _conv.double_.  This is  also  in
      ISO C.

    4 Function names can be overloaded; _over_.

    5 Operators can be overloaded; _over.oper_.

    6 Functions can be inline substituted; _dcl.fct.spec_.

    7 Data objects can be const; _dcl.type_.  This is also in ISO C.

    8 Objects   of   reference   type   can   be   declared;  _dcl.ref_  and
      _dcl.init.ref_.

    9 A free store is provided by the new and delete operators;  _expr.new_,
      _expr.delete_.

    10Classes  can provide data hiding (_class.access_), guaranteed initial-
      ization (_class.ctor_), user-defined conversions  (_class.conv_),  and
      dynamic typing through use of virtual functions (_class.virtual_).

    11The name of a class or enumeration is a type name; _class_.

    12A  pointer  to  any  non-const  and  non-volatile  object  type can be
      assigned to a void*; _conv.ptr_.  This is also in ISO C.

    13A pointer to function can be assigned to a void*; _conv.ptr_.

    14A declaration within a block is a statement; _stmt.dcl_.

    15Anonymous unions can be declared; _class.union_.

      1.1.2  C++ features added since 1985                        [diff.c++]

    1 This subclause summarizes the major extensions of C++ since  the  1985
      version of this manual:

    2 A  class  can  have  more than one direct base class (multiple inheri-
      tance); _class.mi_.

    3 Class members can be protected; _class.access_ .

    4 Pointers to class  members  can  be  declared  and  used;  _dcl.mptr_,
      _expr.mptr.oper_.

    5 Operators  new  and delete can be overloaded and declared for a class;
      _expr.new_, _expr.delete_, _class.free_.  This allows the  "assignment
      to this" technique for class specific storage management to be removed
      to the anachronism subclause; _diff.this_.

    6 Objects can be explicitly destroyed; _class.dtor_.

    7 Assignment and initialization are defined as memberwise assignment and
      initialization; _class.copy_.

    8 The  overload  keyword was made redundant and moved to the anachronism
      subclause; _diff.anac_.

    9 General expressions are allowed as initializers  for  static  objects;
      _dcl.init_.

    10Data objects can be volatile; _dcl.type_.  Also in ISO C.

    11Initializers are allowed for static class members; _class.static_.

    12Member functions can be static; _class.static_.

    13Member functions can be const and volatile; _class.this_.

    14Linkage  to  non-C++  program  fragments  can  be explicitly declared;
      _dcl.link_.

    15Operators ->, ->*, and , can be overloaded; _over.oper_.

    16Classes can be abstract; _class.abstract_.

    17Prefix and postfix application of ++ and -- on a user-defined type can
      be distinguished.

    18Templates; _temp_.

    19Exception handling; _except_.

    20The bool type (_basic.fundamental_).

      1.2  C++ and ISO C                                          [diff.iso]

    1 The  subclauses of this subclause list the differences between C++ and
      ISO C, by the chapters of this document.

      1.2.1  Clause _lex_: lexical conventions                    [diff.lex]

      Subclause _lex.trigraph_

    1 Change: C++ style comments (//) are added
      A pair of slashes now introduce a one-line comment.
      Rationale: This style of comments is a useful  addition  to  the  lan-
      guage.
      Effect  on  original feature: Change to semantics of well-defined fea-
      ture.  A valid ISO C expression containing a  division  operator  fol-
      lowed  immediately  by  a C-style comment will now be treated as a C++
      style comment.  For example:
              {
                  int a = 4;
                  int b = 8 //* divide by a*/ a;
                  +a;
              }
      Difficulty of converting: Syntactic transformation.   Just  add  white
      space after the division operator.
      How widely used: The token sequence //* probably occurs very seldom.

      Subclause _lex.key_

    2 Change: New Keywords
      New keywords are added to C++; see _lex.key_.
      Rationale:  These  keywords  were  added in order to implement the new
      semantics of C++.
      Effect on original feature: Change to semantics of  well-defined  fea-
      ture.   Any  ISO  C  programs  that  used  any  of  these  keywords as

      identifiers are not valid C++ programs.
      Difficulty of converting: Syntactic  transformation.   Converting  one
      specific  program  is  easy.  Converting a large collection of related
      programs takes more work.
      How widely used: Common.

      Subclause _lex.ccon_

    3 Change: Type of character literal is changed from int to char
      Rationale: This is needed for improved  overloaded  function  argument
      type matching.  For example:
              int function( int i );
              int function( char c );

              function( 'x' );
      It  is  preferable that this call match the second version of function
      rather than the first.
      Effect on original feature: Change to semantics of  well-defined  fea-
      ture.  ISO C programs which depend on
              sizeof('x') == sizeof(int)
      will not work the same as C++ programs.
      Difficulty of converting: Simple.
      How  widely  used: Programs which depend upon sizeof('x') are probably
      rare.

      Subclause _lex.string:

    4 Change: String literals made const
      The type of a string literal is changed from `array of char´' to "array
      of  const  char."   The  type of a wide string literal is changed from
      "array of wchar_t" to "array of const wchar_t."
      Rationale: This avoids calling an inappropriate  overloaded  function,
      which might expect to be able to modify its argument.
      Effect  on  original feature: Change to semantics of well-defined fea-
      ture.
      Difficulty of converting:  Simple  syntactic  transformation,  because
      string  literals  can be converted to char*; (_conv.array_).  The most
      common cases are handled by a new but deprecated standard conversion:
              char* p = "abc";                // valid in C, deprecated in C++
              char* q = expr ? "abc" : "de";  // valid in C, invalid in C++
      How widely used: Programs that  have  a  legitimate  reason  to  treat
      string literals as pointers to potentially modifiable memory are prob-
      ably rare.

      1.2.2  Clause _basic_: basic concepts                     [diff.basic]

      Subclause _basic.def_

    1 Change: C++ does not have "tentative definitions" as in C
      E.g., at file scope,

              int i;
              int i;
      is valid in C, invalid in C++.  This makes  it  impossible  to  define
      mutually  referential  file-local  static objects, if initializers are
      restricted to the syntactic forms of C.  For example,
              struct X { int i; struct X *next; };

              static struct X a;
              static struct X b = { 0, &a };
              static struct X a = { 1, &b };
      Rationale: This  avoids  having  different  initialization  rules  for
      built-in types and user-defined types.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation. In  C++,  the  ini-
      tializer  for  one  of a set of mutually-referential file-local static
      objects must invoke a function call to achieve the initialization.
      How widely used: Seldom.

      Subclause _basic.scope_

    2 Change: A struct is a scope in C++, not in C
      Rationale: Class scope is crucial to C++, and a struct is a class.
      Effect on original feature: Change to semantics of  well-defined  fea-
      ture.
      Difficulty of converting: Semantic transformation.
      How  widely  used: C programs use struct extremely frequently, but the
      change is only noticeable  when  struct,  enumeration,  or  enumerator
      names  are  referred  to  outside  the struct.  The latter is probably
      rare.

      Subclause _basic.link_ [also _dcl.type_]

    3 Change: A name of file scope that is explicitly  declared  const,  and
      not  explicitly  declared  extern, has internal linkage, while in C it
      would have external linkage
      Rationale: Because const objects can be used as compile-time values in
      C++,  this  feature  urges programmers to provide explicit initializer
      values for each const.  This feature allows  the  user  to  put  const
      objects in header files that are included in many compilation units.
      Effect  on  original feature: Change to semantics of well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation
      How widely used: Seldom

      Subclause _basic.start_

    4 Change: Main cannot be called recursively and cannot have its  address
      taken
      Rationale: The  main  function may require special actions.
      Effect  on  original  feature:  Deletion  of semantically well-defined

      feature
      Difficulty of converting: Trivial:  create  an  intermediary  function
      such as mymain(argc, argv).
      How widely used: Seldom

      Subclause _basic.types_

    5 Change: C allows "compatible types" in several places, C++ does not
      For example, otherwise-identical struct types with different tag names
      are "compatible" in C but are distinctly different types in C++.
      Rationale: Stricter type checking is essential for C++.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty  of converting: Semantic transformation The "typesafe link-
      age" mechanism will find many, but not all, of such  problems.   Those
      problems not found by typesafe linkage will continue to function prop-
      erly, according to the "layout compatibility rules" of  this  Interna-
      tional Standard.
      How widely used: Common.

      Subclause _conv.ptr_

    6 Change: Converting void* to a pointer-to-object type requires casting
              char a[10];
              void *b=a;
              void foo() {
              char *c=b;
              }
      ISO  C  will  accept this usage of pointer to void being assigned to a
      pointer to object type. C++ will not.
      Rationale: C++ tries  harder  than  C  to  enforce  compile-time  type
      safety.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Could  be  automated.   Violations  will  be
      diagnosed  by the C++ translator. The fix is to add a  cast. For exam-
      ple:
              char *c = (char *) b;
      How widely used: This is fairly widely used but it is good programming
      practice to add the cast when assigning pointer-to-void to pointer-to-
      object. Some ISO C translators will give a warning if the cast is  not
      used.

      Subclause _conv.ptr_

    7 Change:  Only  pointers  to  non-const and non-volatile objects may be
      implicitly converted to void*
      Rationale: This improves type safety.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty  of converting: Could be automated.  A C program containing

      such an implicit conversion from  (e.g.)   pointer-to-const-object  to
      void*  will receive a diagnostic message.  The correction is to add an
      explicit cast.
      How widely used: Seldom.

      1.2.3  Clause _expr_: expressions                          [diff.expr]

      Subclause _expr.call_

    1 Change: Implicit declaration of functions is not allowed
      Rationale: The type-safe nature of C++.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.   Note: the original feature was labeled as "obsolescent" in ISO
      C.
      Difficulty of converting: Syntactic  transformation.   Facilities  for
      producing explicit function declarations are fairly widespread commer-
      cially.
      How widely used: Common.

      Subclause _expr.sizeof_, _expr.cast_

    2 Change: Types must be declared in declarations, not in expressions
      In C, a sizeof expression or cast expression may create  a  new  type.
      For example,
              p = (void*)(struct x {int i;} *)0;
      declares a new type, struct x .
      Rationale:  This prohibition helps to clarify the location of declara-
      tions in the source code.
      Effect on original feature: Deletion of  a  semantically  well-defined
      feature.
      Difficulty of converting: Syntactic transformation.
      How widely used: Seldom.

      1.2.4  Clause _stmt.stmt_: statements                      [diff.stat]

      Subclause _stmt.switch_, _stmt.goto_ (switch and goto statements)

    1 Change:  It is now invalid to jump past a declaration with explicit or
      implicit initializer (except across entire block not entered)
      Rationale: Constructors used in initializers  may  allocate  resources
      which  need  to be de-allocated upon leaving the block.  Allowing jump
      past initializers would require complicated run-time determination  of
      allocation.  Furthermore, any use of the uninitialized object could be
      a disaster.  With this simple compile-time rule, C++ assures  that  if
      an  initialized  variable is in scope, then it has assuredly been ini-
      tialized.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.
      How widely used: Seldom.

      Subclause _stmt.return_

    2 Change:  It is now invalid to return (explicitly or implicitly) from a
      function which is declared to return a value without actually  return-
      ing a value
      Rationale:  The  caller and callee may assume fairly elaborate return-
      value mechanisms for the return of class objects.  If some flow  paths
      execute a return without specifying any value, the implementation must
      embody many more complications.  Besides, promising to return a  value
      of  a given type, and then not returning such a value, has always been
      recognized to be a questionable practice, tolerated only because very-
      old  C had no distinction between void  functions and  int  functions.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.  Add an appropriate
      return value to the source code, e.g. zero.
      How widely used: Seldom.  For several years, many existing C implemen-
      tations have produced warnings in this case.

      1.2.5  Clause _dcl.dcl_: declarations                       [diff.dcl]

      Subclause _dcl.stc_

    1 Change: In C++, the static or extern specifiers can only be applied to
      names of objects or functions
      Using these specifiers with type declarations is illegal in  C++.   In
      C, these specifiers are ignored when used on type declarations.  Exam-
      ple:
              static struct S {      // valid C, invalid in C++
              int i;
              // ...
              };
      Rationale: Storage class specifiers don't have any meaning when  asso-
      ciated  with  a  type.   In C++, class members can be defined with the
      static storage class specifier.  Allowing storage class specifiers  on
      type declarations could render the code confusing for users.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Syntactic transformation.
      How widely used: Seldom.

      Subclause _dcl.typedef_

    2 Change: A C++ typedef name must be different from any class type  name
      declared  in the same scope (except if the typedef is a synonym of the
      class name with the same name). In C, a typedef name and a struct  tag
      name  declared  in the same scope can have the same name (because they
      have different name spaces)
      Example:

              typedef struct name1 { /*...*/ } name1; // valid C and C++
              struct name { /*...*/ };
              typedef int name;                  // valid C, invalid C++
      Rationale: For ease of use, C++ doesn't require that a  type  name  be
      prefixed  with the keywords class, struct or union when used in object
      declarations or type casts.  Example:
              class name { /*...*/ };
              name i;                   // i has type 'class name'
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.  One of the 2 types
      has to be renamed.
      How widely used: Seldom.

      Subclause _dcl.type_ [see also _basic.link_]

    3 Change: const objects must be initialized  in  C++  but  can  be  left
      uninitialized in C
      Rationale: A const object cannot be assigned to so it must be initial-
      ized to hold a useful value.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.
      How widely used: Seldom.

      Subclause _dcl.type_ (type specifiers)

    4 Change: Banning implicit int
      In  C++  a  decl-specifier-seq  must contain a type-specifier.  In the
      following example, the left-hand column presents valid C;  the  right-
      hand column presents equivalent C++:
      void f(const parm);            void f(const int parm);
      const n = 3;                   const int n = 3;
      main()                         int main()
          /* ... */                      /* ... */
      Rationale:  In  C++,  implicit  int  creates several opportunities for
      ambiguity between expressions involving function-like casts and decla-
      rations.  Explicit declaration is increasingly considered to be proper
      style.  Liaison with WG14 (C) indicated support for (at least)  depre-
      cating implicit int in the next revision of C.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Syntactic transformation.   Could  be  auto-
      mated.
      How widely used: Common.

      Subclause _dcl.enum_

    5 Change: C++ objects of enumeration type can only be assigned values of
      the same enumeration type. In C, objects of enumeration  type  can  be
      assigned values of any integral type

      Example:
              enum color { red, blue, green };
              color c = 1;   // valid C, invalid C++
      Rationale: The type-safe nature of C++.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Syntactic transformation.  (The  type  error
      produced  by the assignment can be automatically corrected by applying
      an explicit cast.)
      How widely used: Common.

      Subclause _dcl.enum_

    6 Change: In C++, the type of an enumerator is its  enumeration.  In  C,
      the type of an enumerator is int.
      Example:
              enum e { A };
              sizeof(A) == sizeof(int)  // in C
              sizeof(A) == sizeof(e)    // in C++
              /* and sizeof(int) is not necessary equal to sizeof(e) */
      Rationale: In C++, an enumeration is a distinct type.
      Effect  on  original feature: Change to semantics of well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.
      How widely used: Seldom.  The only time this affects existing  C  code
      is  when  the  size  of an enumerator is taken.  Taking the size of an
      enumerator is not a common C coding practice.

      1.2.6  Clause _dcl.decl_: declarators                      [diff.decl]

      Subclause _dcl.fct_

    1 Change: In C++, a function declared with an empty parameter list takes
      no arguments.
      In  C,  an  empty parameter list means that the number and type of the
      function arguments are unknown" Example:
              int f();  // means   int f(void)     in C++
                            //         int f(unknown)  in C
      Rationale: This is to avoid erroneous function  calls  (i.e.  function
      calls with the wrong number or type of arguments).
      Effect  on  original feature: Change to semantics of well-defined fea-
      ture.  This feature was marked as "obsolescent" in C.
      Difficulty of converting: Syntactic transformation.  The function dec-
      larations  using  C  incomplete declaration style must be completed to
      become full prototype declarations.  A program may need to be  updated
      further  if  different calls to the same (non-prototype) function have
      different numbers of arguments or if the type of  corresponding  argu-
      ments differed.
      How widely used: Common.

      Subclause _dcl.fct_ [see _expr.sizeof_]

    2 Change: In C++, types may not be defined in return or parameter types.
      In C, these type definitions are allowed
      Example:
              void f( struct S { int a; } arg ) {}     // valid C, invalid C++
              enum E { A, B, C } f() {}                // valid C, invalid C++
      Rationale: When comparing types in different  compilation  units,  C++
      relies  on  name  equivalence when C relies on structural equivalence.
      Regarding parameter types: since the type defined in an parameter list
      would  be  in  the  scope of the function, the only legal calls in C++
      would be from within the function itself.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty  of  converting: Semantic transformation.  The type defini-
      tions must be moved to file scope, or in header files.
      How widely used: Seldom.  This style of type definitions  is  seen  as
      poor coding style.

      Subclause _dcl.fct.def_

    3 Change:  In C++, the syntax for function definition excludes the "old-
      style" C function. In C, "old-style" syntax is allowed, but deprecated
      as "obsolescent."
      Rationale: Prototypes are essential to type safety.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Syntactic transformation.
      How widely used: Common in old programs, but already known to be obso-
      lescent.

      Subclause _dcl.init.string_

    4 Change: In C++, when initializing an array of character with a string,
      the number of characters in  the  string  (including  the  terminating
      '\0')  must  not  exceed the number of elements in the array. In C, an
      array can be initialized with a string even if the array is not  large
      enough to contain the string terminating '\0'
      Example:
              char array[4] = "abcd";    // valid C, invalid C++
      Rationale:  When  these non-terminated arrays are manipulated by stan-
      dard string routines, there is potential for major catastrophe.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.  The arrays must be
      declared one element bigger to contain the string terminating '\0'.
      How widely used: Seldom.  This style of array initialization  is  seen
      as poor coding style.

      1.2.7  Clause _class_: classes                            [diff.class]

      Subclause _class.name_ [see also _dcl.typedef_]

    1 Change: In C++, a class declaration introduces the class name into the
      scope where it is declared and hides any  object,  function  or  other
      declaration  of  that name in an enclosing scope. In C, an inner scope
      declaration of a struct tag name never hides the name of an object  or
      function in an outer scope
      Example:
              int x[99];
              void f()
              {
                      struct x { int a; };
                      sizeof(x);  /* size of the array in C    */
                      /* size of the struct in C++ */
              }
      Rationale:  This is one of the few incompatibilities between C and C++
      that can be attributed to the new C++ name space  definition  where  a
      name  can  be  declared  as  a type and as a nontype in a single scope
      causing the nontype name to hide the type name and requiring that  the
      keywords  class,  struct,  union  or enum be used to refer to the type
      name.  This new name space definition  provides  important  notational
      conveniences  to C++ programmers and helps making the use of the user-
      defined types as similar as possible to the  use  of  built-in  types.
      The  advantages  of  the new name space definition were judged to out-
      weigh by far the incompatibility with C described above.
      Effect on original feature: Change to semantics of  well-defined  fea-
      ture.
      Difficulty of converting: Semantic transformation.  If the hidden name
      that needs to be accessed is at global scope, the :: C++ operator  can
      be used.  If the hidden name is at block scope, either the type or the
      struct tag has to be renamed.
      How widely used: Seldom.

      Subclause _class.nest_

    2 Change: In C++, the name of a nested class is local to  its  enclosing
      class.  In C the name of the nested class belongs to the same scope as
      the name of the outermost enclosing class
      Example:
              struct X {
                      struct Y { /* ... */ } y;
              };
              struct Y yy;     // valid C, invalid C++
      Rationale: C++  classes  have  member  functions  which  require  that
      classes establish scopes.  The C rule would leave classes as an incom-
      plete scope mechanism which would prevent C++ programmers  from  main-
      taining  locality  within  a class.  A coherent set of scope rules for
      C++ based on the C rule would be very complicated and C++  programmers
      would  be  unable to predict reliably the meanings of nontrivial exam-
      ples involving nested or local functions.
      Effect on original feature: Change of semantics of  well-defined  fea-
      ture.
      Difficulty of converting: Semantic transformation.  To make the struct
      type name visible in the scope of the enclosing struct, the struct tag
      could  be  declared  in  the scope of the enclosing struct, before the

      enclosing struct is defined. Example:
              struct Y;  // struct Y and struct X are at the same scope
              struct X {
                      struct Y { /* ... */ } y;
              };
      All the definitions of C struct types enclosed in other struct defini-
      tions and accessed outside the scope of the enclosing struct could  be
      exported to the scope of the enclosing struct.  Note: this is a conse-
      quence of the difference in scope rules, which is documented  at  sub-
      clause _basic.scope_ above.
      How widely used: Seldom.

      Subclause _class.nested.type_

    3 Change:  In C++, a typedef name may not be redefined in a class decla-
      ration after being used in the declaration
      Example:
              typedef int I;
              struct S {
                      I i;
                      int I;       // valid C, invalid C++
              };
      Rationale: When classes become complicated, allowing such a  redefini-
      tion  after  the  type has been used can create confusion for C++ pro-
      grammers as to what the meaning of 'I' really is.
      Effect on original feature: Deletion of semantically well-defined fea-
      ture.
      Difficulty of converting: Semantic transformation.  Either the type or
      the struct member has to be renamed.
      How widely used: Seldom.

      1.2.8  Clause _special_: special member functions       [diff.special]

      Subclause _class.copy_ (copying class objects)

    1 Change: Copying volatile objects
      The implicitly-declared copy constructor and implicitly-declared  copy
      assignment  operator  cannot  make  a  copy of a volatile lvalue.  For
      example, the following is valid in ISO C:
      struct X { int i; };
      struct X x1, x2;
      volatile struct X x3 = {0};
      x1 = x3; // invalid C++
      x2 = x3; // also invalid C++
      Rationale: Several alternatives were debated at length.  Changing  the
      parameter to volatile const X& would greatly complicate the generation
      of efficient code for class  objects.   Discussion  of  providing  two
      alternative  signatures for these implicitly-defined operations raised
      unanswered concerns about creating ambiguities  and  complicating  the
      rules  that  specify the formation of these operators according to the
      bases and members.
      Effect on original  feature:  Deletion  of  semantically  well-defined

      feature.
      Difficulty of converting: Semantic transformation.  If volatile seman-
      tics are required for the copy, a user-declared constructor or assign-
      ment  must  be  provided.   If non-volatile semantics are required, an
      explicit const_cast can be used.
      How widely used: Seldom.

      1.2.9  Clause _cpp_: preprocessing directives               [diff.cpp]

      Subclause _cpp.predefined_ (predefined names)

    1 Change: Whether __STDC__ is defined and if so, what its value is,  are
      implementation-defined
      Rationale:  C++  is not identical to ISO C. Mandating that __STDC__ be
      defined would require that translators make an incorrect claim.   Each
      implementation  must  choose  the behavior that will be most useful to
      its marketplace.
      Effect on original feature: Change to semantics of  well-defined  fea-
      ture.
      Difficulty of converting: Semantic transformation.
      How  widely  used:  Programs  and  headers that reference __STDC__ are
      quite common.

      1.3  Anachronisms                                          [diff.anac]

    1 The extensions presented here may be provided by an implementation  to
      ease  the  use  of C programs as C++ programs or to provide continuity
      from earlier C++ implementations.  Note that each  of  these  features
      has undesirable aspects.  An implementation providing them should also
      provide a way for the user to ensure that  they  do  not  occur  in  a
      source  file.   A  C++  implementation is not obliged to provide these
      features.

    2 The word overload may be used as a  decl-specifier  (_dcl.dcl_)  in  a
      function  declaration  or a function definition.  When used as a decl-
      specifier, overload is a reserved word and cannot also be used  as  an
      identifier.

    3 The  definition  of a static data member of a class for which initial-
      ization by default to all zeros applies  (_dcl.init_,  _class.static_)
      may be omitted.

    4 An old style (that is, pre-ISO C) C preprocessor may be used.

    5 An int may be assigned to an object of enumeration type.

    6 The  number  of elements in an array may be specified when deleting an
      array of a type for which there is no destructor; _expr.delete_.

    7 A single function operator++() may be used to overload both prefix and
      postfix  ++ and a single function operator--() may be used to overload
      both prefix and postfix --; _over.ref_.

      1.3.1  Old style function definitions                   [diff.fct.def]

    1 The C function definition syntax
              old-function-definition:
                      decl-specifiersopt old-function-declarator declaration-seqopt function-body
              old-function-declarator:
                      declarator ( parameter-listopt )
              parameter-list:
                      identifier
                      parameter-list , identifier
      For example,
              max(a,b) int b; { return (a<b) ? b : a; }
      may be used.  If a function defined like this has not been  previously
      declared  its  parameter  type  will  be  taken  to be (...), that is,
      unchecked.  If it has been declared its type must agree with  that  of
      the declaration.

    2 Class member functions may not be defined with this syntax.

      1.3.2  Old style base class initializer               [diff.base.init]

    1 In  a mem-initializer(_class.base.init_), the class-name naming a base
      class may be left out provided there is  exactly  one  immediate  base
      class.  For example,
              class B {
                  // ...
              public:
                  B (int);
              };
              class D : public B {
                  // ...
                  D(int i) : (i) { /* ... */ }
              };
      causes the B constructor to be called with the argument i.

      1.3.3  Assignment to this                                  [diff.this]

    1 Memory management for objects of a specific class can be controlled by
      the user by suitable assignments to the this pointer.  By assigning to
      the  this pointer before any use of a member, a constructor can imple-
      ment its own storage allocation.  By assigning  the  null  pointer  to
      this,  a  destructor can avoid the standard deallocation operation for
      objects of its class.   Assigning  the  null  pointer  to  this  in  a
      destructor also suppressed the implicit calls of destructors for bases
      and members.  For example,
              class Z {
                  int z[10];
                  Z()  { this = my_allocator( sizeof(Z) ); }
                  ~Z() { my_deallocator( this ); this = 0; }
              };

    2 On entry into a constructor, this is nonnull if allocation has already
      taken place (as it will have for auto, static, and member objects) and
      null otherwise.

    3 Calls to constructors for a base class and  for  member  objects  will
      take place (only) after an assignment to this.  If a base class's con-
      structor assigns to this, the new value  will  also  be  used  by  the
      derived class's constructor (if any).

    4 Note  that  if  this  anachronism  exists  either the type of the this
      pointer cannot be a *const or the enforcement of the rules for assign-
      ment to a constant pointer must be subverted for the this pointer.

      1.3.4  Cast of bound pointer                              [diff.bound]

    1 A  pointer to member function for a particular object may be cast into
      a pointer to function, for example, (int(*)())p->f.  The result  is  a
      pointer  to the function that would have been called using that member
      function for that particular object.  Any use of the resulting pointer
      is - as ever - undefined.

      1.3.5  Nonnested classes                        [diff.class.nonnested]

    1 Where  a  class is declared within another class and no other class of
      that name is declared in the program that class can be used as  if  it
      was declared outside its enclosing class (exactly as a C struct).  For
      example,
              struct S {
                  struct T {
                      int a;
                  };
                  int b;
              };

              struct T x;     // meaning `S::T x;'

      1.4  Standard C library                                 [diff.library]

    1 This subclause summarizes the contents of  the  C++  Standard  library
      included from the Standard C library.  It also summarizes the explicit
      changes in definitions, declarations, or  behavior  from  the  ISO/IEC
      9899:1990  and  ISO/IEC  9899:1990/DAM  1  noted  in  other subclauses
      (_lib.headers_, _lib.support.types_, _lib.c.strings_).

    2 The C++ Standard library  provides  54  standard  macros  from  the  C
      library, as shown in Table 1.

    3 The  header names (enclosed in < and >) indicate that the macro may be
      defined in more than one header.  All such definitions are  equivalent
      (_basic.def.odr_).

                             Table 1--Standard Macros

      +----------------------------------------------------------------------------+
      |assert           HUGE_VAL         NULL <cstring>   SIGILL    va_arg         |
      |BUFSIZ           LC_ALL           NULL <ctime>     SIGINT    va_end         |
      |CLOCKS_PER_SEC   LC_COLLATE       NULL <cwchar>    SIGSEGV   va_start       |
      |EDOM             LC_CTYPE         offsetof         SIGTERM   WCHAR_MAX      |
      |EOF              LC_MONETARY      RAND_MAX         SIG_DFL   WCHAR_MIN      |
      |ERANGE           LC_NUMERIC       SEEK_CUR         SIG_ERR   WEOF <cwchar>  |
      |errno            LC_TIME          SEEK_END         SIG_IGN   WEOF <cwctype> |
      |EXIT_FAILURE     L_tmpnam         SEEK_SET         stderr    _IOFBF         |
      |EXIT_SUCCESS     MB_CUR_MAX       setjmp           stdin     _IOLBF         |
      |FILENAME_MAX     NULL <cstddef>   SIGABRT          stdout    _IONBF         |
      |FOPEN_MAX        NULL <cstdio>    SIGFPE           TMP_MAX                  |
      +----------------------------------------------------------------------------+

    4 The  C++  Standard  library  provides  45  standard  values from the C
      library, as shown in Table 2:

                             Table 2--Standard Values

         +---------------------------------------------------------------+
         |CHAR_BIT         FLT_DIG          INT_MIN           MB_LEN_MAX |
         |CHAR_MAX         FLT_EPSILON      LDBL_DIG          SCHAR_MAX  |
         |CHAR_MIN         FLT_MANT_DIG     LDBL_EPSILON      SCHAR_MIN  |
         |DBL_DIG          FLT_MAX          LDBL_MANT_DIG     SHRT_MAX   |
         |DBL_EPSILON      FLT_MAX_10_EXP   LDBL_MAX          SHRT_MIN   |
         |DBL_MANT_DIG     FLT_MAX_EXP      LDBL_MAX_10_EXP   UCHAR_MAX  |
         |DBL_MAX          FLT_MIN          LDBL_MAX_EXP      UINT_MAX   |
         |DBL_MAX_10_EXP   FLT_MIN_10_EXP   LDBL_MIN          ULONG_MAX  |
         |DBL_MAX_EXP      FLT_MIN_EXP      LDBL_MIN_10_EXP   USHRT_MAX  |
         |DBL_MIN          FLT_RADIX        LDBL_MIN_EXP                 |
         |DBL_MIN_10_EXP   FLT_ROUNDS       LONG_MAX                     |
         |DBL_MIN_EXP      INT_MAX          LONG_MIN                     |
         +---------------------------------------------------------------+

    5 The C++ Standard  library  provides  19  standard  types  from  the  C
      library, as shown in Table 3:

                             Table 3--Standard Types

        +-----------------------------------------------------------------+
        |clock_t   ldiv_t             size_t <cstdio>    wctrans_t        |
        |div_t     mbstate_t          size_t <cstring>   wctype_t         |
        |FILE      ptrdiff_t          size_t <ctime>     wint_t <cwchar>  |
        |fpos_t    sig_atomic_t       time_t             wint_t <cwctype> |
        |jmp_buf   size_t <cstddef>   va_list                             |
        +-----------------------------------------------------------------+

    6 The  C++  Standard  library  provides 2 standard structures from the C
      library, as shown in Table 4:

                            Table 4--Standard Structs

                                   +-----------+
                                   |lconv   tm |
                                   +-----------+

    7 The C++ Standard library provides 209 standard functions  from  the  C
      library, as shown in Table 5:

                           Table 5--Standard Functions

      +---------------------------------------------------------------------------------+
      |abort      fgetpos    gmtime       log10       rename      strtok      wcscpy    |
      |abs        fgets      isalnum      longjmp     rewind      strtol      wcscspn   |
      |acos       fgetwc     isalpha      malloc      scanf       strtoul     wcsftime  |
      |asctime    fgetws     iscntrl      mblen       setbuf      strxfrm     wcslen    |
      |asin       floor      isdigit      mbrlen      setlocale   swprintf    wcsncat   |
      |atan       fmod       isgraph      mbrtowc     setvbuf     swscanf     wcsncmp   |
      |atan2      fopen      islower      mbsinit     signal      system      wcsncpy   |
      |atexit     fprintf    isprint      mbsrtowcs   sin         tan         wcspbrk   |
      |atof       fputc      ispunct      mbstowcs    sinh        tanh        wcsrchr   |
      |atoi       fputs      isspace      mbtowc      sprintf     time        wcsrtombs |
      |atol       fputwc     isupper      memchr      sqrt        tmpfile     wcsspn    |
      |bsearch    fputws     iswalnum     memcmp      srand       tmpnam      wcsstr    |
      |btowc      fread      iswalpha     memcpy      sscanf      tolower     wcstod    |
      |calloc     free       iswcntrl     memmove     strcat      toupper     wcstok    |
      |ceil       freopen    iswctype     memset      strchr      towctrans   wcstol    |
      |clearerr   frexp      iswdigit     mktime      strcmp      towlower    wcstombs  |
      |clock      fscanf     iswgraph     modf        strcoll     towupper    wcstoul   |
      |cos        fseek      iswlower     perror      strcpy      ungetc      wcsxfrm   |
      |cosh       fsetpos    iswprint     pow         strcspn     ungetwc     wctob     |
      |ctime      ftell      iswpunct     printf      strerror    vfprintf    wctomb    |
      |difftime   fwide      iswspace     putc        strftime    vfwprintf   wctrans   |
      |div        fwprintf   iswupper     putchar     strlen      vprintf     wctype    |
      |exit       fwrite     iswxdigit    puts        strncat     vsprintf    wmemchr   |
      |exp        fwscanf    isxdigit     putwc       strncmp     vswprintf   wmemcmp   |
      |fabs       getc       labs         putwchar    strncpy     vwprintf    wmemcpy   |
      |fclose     getchar    ldexp        qsort       strpbrk     wcrtomb     wmemmove  |
      |feof       getenv     ldiv         raise       strrchr     wcscat      wmemset   |
      |ferror     gets       localeconv   rand        strspn      wcschr      wprintf   |
      |fflush     getwc      localtime    realloc     strstr      wcscmp      wscanf    |
      |fgetc      getwchar   log          remove      strtod      wcscoll               |
      +---------------------------------------------------------------------------------+

      1.4.1  Modifications to headers                 [diff.mods.to.headers]

    1 For  compatibility  with  the  Standard  C  library,  the C++ Standard
      library provides the 18 C headers (_depr.c.headers_), but their use is
      deprecated in C++.

      1.4.2  Modifications to definitions         [diff.mods.to.definitions]

      1.4.2.1  Type wchar_t                                   [diff.wchar.t]

    1 wchar_t  is  a keyword in this International Standard (_lex.key_).  It
      does not appear as a type name defined in any of <cstddef>, <cstdlib>,
      or <cwchar> (_lib.c.strings_).

      1.4.2.2  Header <iso646.h>                      [diff.header.iso646.h]

    1 The  tokens and, and_eq, bitand, bitor, compl, not_eq, not, or, or_eq,
      xor,  and  xor_eq  are  keywords  in   this   International   Standard
      (_lex.key_).   They do not appear as macro names defined in <ciso646>.

      1.4.2.3  Macro NULL                                        [diff.null]

    1 The macro NULL, defined in  any  of  <clocale>,  <cstddef>,  <cstdio>,
      <cstdlib>,  <cstring>,  <ctime>,  or  <cwchar>,  is an implementation-
      defined C++  null-pointer  constant  in  this  International  Standard
      (_lib.support.types_).

      1.4.3  Modifications to declarations       [diff.mods.to.declarations]

    1 Header <cstring>: The following functions have different declarations:

      --strchr

      --strpbrk

      --strrchr

      --strstr

      --memchr

    2 Subclause (_lib.c.strings_) describes the changes.

      1.4.4  Modifications to behavior               [diff.mods.to.behavior]

    1 Header <cstdlib>: The following functions have different behavior:

      --atexit

      --exit

      Subclause (_lib.support.start.term_) describes the changes.

    2 Header <csetjmp>: The following functions have different behavior:

      --longjmp

      Subclause (_lib.support.runtime_) describes the changes.

      1.4.4.1  Macro offsetof(type, member-designator)       [diff.offsetof]

    1 The macro offsetof, defined in <cstddef>, accepts a restricted set  of
      type  arguments  in this International Standard.  Subclause (_lib.sup-
      port.types_) describes the change.

      1.4.4.2  Memory allocation functions                     [diff.malloc]

    1 The functions calloc, malloc,  and  realloc  are  restricted  in  this
      International  Standard.   Subclause  (_lib.c.malloc_)  describes  the
      changes.