Полезная информация


  ______________________________________________________________________

  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.