______________________________________________________________________

  Annex C (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.

  C.1  Extensions                                               [diff.c]

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

  C.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_.

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

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

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

  feature.   Any ISO C programs that used any of these keywords as iden­
  tifiers 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.

  C.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 fea­
  ture
  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

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

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

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

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

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

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

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

  C.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 fea­
  ture.
  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.

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

  C.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_.

8
  C.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.

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

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

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

  C.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;'

  C.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<cstddef>   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 208 standard functions from the C
  library, as shown in Table 5:

                       Table 5--Standard Functions

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

  C.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++.

  C.4.2  Modifications to definitions         [diff.mods.to.definitions]

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

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

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

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

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

  C.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.support.types_) describes the change.

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