Annex C [diff]

(informative) Compatibility

C.1 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.1.1 Clause 2: lexical conventions [diff.lex]

2.3

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 language. Effect on original feature: Change to semantics of well-defined feature. A valid ISO C expression containing a division operator followed 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. 2.11

2 Change: New Keywords New keywords are added to C++; see 2.11. 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 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. 2.13.2

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 feature. 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 feature. Difficulty of converting: Simple syntactic transformation, because string literals can be converted to char*; (4.2). 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 probably rare.

C.1.2 Clause 3: basic concepts [diff.basic]

3.1

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 feature. Difficulty of converting: Semantic transformation. In C++, the initializer for one of a set of mutuallyreferential file-local static objects must invoke a function call to achieve the initialization. How widely used: Seldom. 3.3

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 feature. 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. 3.5 [also 7.1.5]

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 feature. Difficulty of converting: Semantic transformation How widely used: Seldom 3.6

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 3.9

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 feature. Difficulty of converting: Semantic transformation. The ``typesafe linkage'' mechanism will find many, but not all, of such problems. Those problems not found by typesafe linkage will continue to function properly, according to the ``layout compatibility rules'' of this International Standard. How widely used: Common. 4.10

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 feature. Difficulty of converting: Could be automated. Violations will be diagnosed by the C++ translator. The fix is to add a cast For example:
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. 4.10

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 feature. 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.1.3 Clause 5: expressions [diff.expr]

5.2.2

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 feature. 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. 5.3.3, 5.4

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 declarations 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.1.4 Clause 6: statements [diff.stat]

6.4.2, 6.6.4 (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 compiletime rule, C++ assures that if an initialized variable is in scope, then it has assuredly been initialized. Effect on original feature: Deletion of semantically well-defined feature. Difficulty of converting: Semantic transformation. How widely used: Seldom. 6.6.3

2 Change: It is now invalid to return (explicitly or implicitly) from a function which is declared to return a value without actually returning 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 feature. 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 implementations have produced warnings in this case.

C.1.5 Clause 7: declarations [diff.dcl]

7.1.1

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. Example:

static struct S {                       //  valid C, invalid in C++
int i;
// ...
};

Rationale: Storage class specifiers don't have any meaning when associated 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 feature. Difficulty of converting: Syntactic transformation. How widely used: Seldom. 7.1.3

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 feature. Difficulty of converting: Semantic transformation. One of the 2 types has to be renamed. How widely used: Seldom. 7.1.5 [see also 3.5]

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 initialized to hold a useful value. Effect on original feature: Deletion of semantically well-defined feature. Difficulty of converting: Semantic transformation. How widely used: Seldom. 7.1.5 (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 declarations. Explicit declaration is increasingly considered to be proper style. Liaison with WG14 (C) indicated support for (at least) deprecating implicit int in the next revision of C. Effect on original feature: Deletion of semantically well-defined feature. Difficulty of converting: Syntactic transformation. Could be automated. How widely used: Common. 7.2

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 feature. 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. 7.2

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 feature. 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.1.6 Clause 8: declarators [diff.decl]

8.3.5

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 feature. This feature was marked as ``obsolescent'' in C. Difficulty of converting: Syntactic transformation. The function declarations 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 arguments differed. How widely used: Common. 8.3.5 [see 5.3.3]

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 feature. Difficulty of converting: Semantic transformation. The type definitions 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. 8.4

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 feature. Difficulty of converting: Syntactic transformation. How widely used: Common in old programs, but already known to be obsolescent. 8.5.2

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 standard string routines, there is potential for major catastrophe. Effect on original feature: Deletion of semantically well-defined feature. 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.1.7 Clause 9: classes [diff.class]

9.1 [see also 7.1.3]

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 outweigh by far the incompatibility with C described above. Effect on original feature: Change to semantics of well-defined feature. 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. 9.7

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 incomplete scope mechanism which would prevent C++ programmers from maintaining 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 examples involving nested or local functions. Effect on original feature: Change of semantics of well-defined feature. 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 definitions and accessed outside the scope of the enclosing struct could be exported to the scope of the enclosing struct. Note: this is a consequence of the difference in scope rules, which is documented in 3.3. How widely used: Seldom. 9.9

3 Change: In C++, a typedef name may not be redefined in a class declaration 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 redefinition after the type has been used can create confusion for C++ programmers as to what the meaning of 'I' really is. Effect on original feature: Deletion of semantically well-defined feature. Difficulty of converting: Semantic transformation. Either the type or the struct member has to be renamed. How widely used: Seldom.

C.1.8 Clause 12: special member functions [diff.special]

12.8 (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 semantics are required for the copy, a userdeclared constructor or assignment must be provided. If non-volatile semantics are required, an explicit const_cast can be used. How widely used: Seldom.

C.1.9 Clause 16: preprocessing directives [diff.cpp]

16.8 (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 feature. Difficulty of converting: Semantic transformation. How widely used: Programs and headers that reference _ _STDC_ _ are quite common.

C.2 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 (17.4.1.2, 18.1, 21.4).

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

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

Table 95---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 96:

Table 96---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 97:

Table 97---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 98:

Table 98---Standard Structs
_ ____________
_ lconv  tm
____________ 

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

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

C.2.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 (D.5), but their use is deprecated in C++.

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

C.2.2.1 Type wchar_t [diff.wchar.t]

1 wchar_t is a keyword in this International Standard (2.11). It does not appear as a type name defined in any of <cstddef>, <cstdlib>, or <cwchar> (21.4). C.2.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 (2.11). They do not appear as macro names defined in <ciso646>.

C.2.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 (18.1).

C.2.3 Modifications to declarations [diff.mods.to.declarations]

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

2 21.4 describes the changes.

C.2.4 Modifications to behavior [diff.mods.to.behavior]

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

18.3 describes the changes.

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

18.7 describes the changes.

C.2.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. 18.1 describes the change.

C.2.4.2 Memory allocation functions [diff.malloc]

1 The functions calloc, malloc, and realloc are restricted in this International Standard. 20.4.6 describes the changes.