______________________________________________________________________ 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 a compiler. 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 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. 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 linkage mechanism will find many, but not all, of such problems. Those prob lems not found by typesafe linkage will continue to function properly, 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 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. 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 compiler 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 compilers 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.enum_ 4 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_ 5 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 _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 explicit changes in definitions, decla rations, or behavior within the Standard C library when it is part of the Standard C++ library. (Subclause _lib.introduction_ imposes some implicit changes in the behavior of the Standard C library.) C.4.1 Modifications to headers [diff.mods.to.headers] 1 For compatibility with the Standard C library, the Standard C++ library provides the 18 C headers, as shown in Table 1: Table 1--C Headers <assert.h> <iso646.h> <setjmp.h> <stdio.h> <wchar.h> <ctype.h> <limits.h> <signal.h> <stdlib.h> <wctype.h> <errno.h> <locale.h> <stdarg.h> <string.h> <float.h> <math.h> <stddef.h> <time.h> 2 Each C header, whose name has the form name.h, includes its corre sponding C++ header cname, followed by an explicit using-declaration (_namespace.udecl_) for each name placed in the standard library namespace by the header (_lib.namespace_).1) _________________________ 1) For example, the header <cstdlib> provides its declarations and definitions within the namespace std. The header <stdlib.h>, makes these available in the global name space, much as in the C Standard. C.4.2 Modifications to definitions [diff.mods.to.definitions] 1 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>, <std def.h>, <cstdlib>, <stdlib.h>, <cwchar>, or <wchar.h>. 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 <iso646.h>. C.4.2.3 Macro NULL [diff.null] 1 The macro NULL, defined in any of <clocale>, <locale.h>, <cstddef>, <stddef.h>, <cstdio>, <stdio.h>, <cstdlib>, <stdlib.h>, <cstring>, <string.h>, <ctime>, <time.h>, <cwchar>, or <wchar.h>, is an implemen tation-defined C++ null-pointer constant in this International Standard.2) C.4.3 Modifications to declarations [diff.mods.to.declarations] 1 Header <string.h>: The following functions have different declara tions: --strchr --strpbrk --strrchr --strstr --memchr Subclause (_lib.c.strings_) describes the changes. C.4.4 Modifications to behavior [diff.mods.to.behavior] 1 Header <stdlib.h>: The following functions have different behavior: atexit --exit Subclause (_lib.support.start.term_) describes the changes. 2 Header <setjmp.h>: The following functions have different behavior: longjmp _________________________ 2) Possible definitions include 0 and 0L, but not (void*)0. Subclause (_lib.support.runtime_) describes the changes. 3 C.4.4.1 Macro offsetof(type, member-designator) [diff.offsetof] <stddef.h> 1 The macro offsetof, defined in <stddef.h>, accepts a restricted set of type arguments in this International Standard. type shall be a POD structure or a POD union. C.4.5 Names with external linkage [diff.extern.c.names] --Each name declared with external linkage in a C header is reserved to the implementation for use as a name with extern "C" linkage. --Each function signature declared with external linkage in a C header is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage.3) 1 It is unspecified whether a name declared with external linkage in a C header has either extern "C" or extern "C++" linkage.4) _________________________ 3) The function signatures declared in <cwchar> and <cwctype> are al ways reserved, notwithstanding the restrictions imposed in subclause 4.5.1 of Amendment 1 to the C Standard for these headers. 4) The only reliable way to declare an object or function signature from the Standard C library is by including the header that declares it, notwithstanding the latitude granted in subclause 7.1.7 of the C Standard.