Annex C (informative) Compatibility [diff]

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

This subclause lists the differences between C++ and ISO C, by the chapters of this document.

C.1.1 Clause [lex]: lexical conventions [diff.lex]

[lex.key]
Change: New Keywords
New keywords are added to C++; see [lex.key].
Rationale: These keywords were added in order to implement the new semantics of C++.
Effect on original feature: Change to semantics of well-defined feature. Any ISO C programs that used any of these keywords as 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.

[lex.ccon]
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]:
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 char16_t string literal is changed from “array of some-integer-type” to “array of const char16_t.” The type of a char32_t string literal is changed from “array of some-integer-type” to “array of const char32_t.” 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: Syntactic transformation. The fix is to add a cast:

char* p = "abc";                // valid in C, invalid in C++
void f(char*) {
  char* p = (char*)"abc";       // OK: cast added
  f(p);
  f((char*)"def");              // OK: cast added
}


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 [basic]: basic concepts [diff.basic]

[basic.def]
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 fundamental types and user-defined types.
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Semantic transformation.
Rationale: In C++, the initializer 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.

[basic.scope]
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.

[basic.link] [also [dcl.type]]
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 constobjects 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

[basic.start]
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

[basic.types]
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.

C.1.3 Clause [conv]: standard conversions [diff.conv]

[conv.ptr]
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.

[conv.ptr]
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.4 Clause [expr]: expressions [diff.expr]

[expr.call]
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.

[expr.sizeof], [expr.cast]
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.

[expr.cond], [expr.ass], [expr.comma]


Change: The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue
Rationale: C++ is an object-oriented language, placing relatively more emphasis on lvalues. For example, functions may return lvalues.
Effect on original feature: Change to semantics of well-defined feature. Some C expressions that implicitly rely on lvalue-to-rvalue conversions will yield different results. For example,

char arr[100];
sizeof(0, arr)

yields 100 in C++ and sizeof(char*) in C.
Difficulty of converting: Programs must add explicit casts to the appropriate rvalue.
How widely used: Rare.

C.1.5 Clause [stmt.stmt]: statements [diff.stat]

[stmt.switch], [stmt.goto]
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 initialized.
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Semantic transformation.
How widely used: Seldom.

[stmt.return]
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, such as zero.
How widely used: Seldom. For several years, many existing C implementations have produced warnings in this case.

C.1.6 Clause [dcl.dcl]: declarations [diff.dcl]

[dcl.stc]
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 declared 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.

[dcl.typedef]
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.

[dcl.type] [see also [basic.link]]
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.

[dcl.type]
Change: Banning implicit int

In C++ a decl-specifier-seq must contain a type-specifier, unless it is followed by a declarator for a constructor, a destructor, or a conversion function. 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.

[dcl.spec.auto]
Change: The keyword auto cannot be used as a storage class specifier.

void f() {
  auto int x;     // valid C, invalid C++
}


Rationale: Allowing the use of auto to deduce the type of a variable from its initializer results in undesired interpretations of auto as a storage class specifier in certain contexts.
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Syntactic transformation.
How widely used: Rare.

[dcl.enum]
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 };
enum 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.

[dcl.enum]
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 necessarily 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.7 Clause [dcl.decl]: declarators [diff.decl]

[dcl.fct]
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.

[dcl.fct] [see [expr.sizeof]]
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.

[dcl.fct.def]
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.

[dcl.init.string]
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.8 Clause [class]: classes [diff.class]

[class.name] [see also [dcl.typedef]]
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 non-type in a single scope causing the non-type 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 fundamental 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.

[class.nest]
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 [basic.scope].
How widely used: Seldom.

[class.nested.type]
Change: In C++, a typedef name may not be redeclared in a class definition after being used in that definition

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.9 Clause [special]: special member functions [diff.special]

[class.copy]
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; };
volatile struct X x1 = {0};
struct X x2(x1);                // invalid C++
struct X x3;
x3 = x1;                        // 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 user-declared constructor or assignment must be provided. [ Note: This user-declared constructor may be explicitly defaulted.  — end note ] If non-volatile semantics are required, an explicit const_cast can be used.
How widely used: Seldom.

C.1.10 Clause [cpp]: preprocessing directives [diff.cpp]

[cpp.predefined]
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 C++ and ISO C++ 2003 [diff.cpp03]

This subclause lists the differences between C++ and ISO C++ 2003 (ISO/IEC 14882:2003, Programming Languages — C++), by the chapters of this document.

C.2.1 Clause [lex]: lexical conventions [diff.cpp03.lex]

[lex.pptoken]
Change: New kinds of string literals
Rationale: Required for new features.
Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard. Specifically, macros named R, u8, u8R, u, uR, U, UR, or LR will not be expanded when adjacent to a string literal but will be interpreted as part of the string literal. For example,

#define u8 "abc"
const char *s = u8"def";        // Previously "abcdef", now "def"

[lex.pptoken]
Change: User-defined literal string support
Rationale: Required for new features.
Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard, as the following example illustrates.

#define _x "there"
"hello"_x         // #1

Previously, #1 would have consisted of two separate preprocessing tokens and the macro _x would have been expanded. In this International Standard, #1 consists of a single preprocessing tokens, so the macro is not expanded.

[lex.key]
Change: New keywords
Rationale: Required for new features.
Effect on original feature: Added to Table [tab:keywords], the following identifiers are new keywords: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, and thread_local. Valid C++ 2003 code using these identifiers is invalid in this International Standard.

[lex.icon]
Change: Type of integer literals
Rationale: C99 compatibility.
Effect on original feature: Certain integer literals larger than can be represented by long could change from an unsigned integer type to signed long long.

C.2.2 Clause [expr]: expressions [diff.cpp03.expr]

[expr.mul]
Change: Specify rounding for results of integer / and %
Rationale: Increase portability, C99 compatibility.
Effect on original feature: Valid C++ 2003 code that uses integer division rounds the result toward 0 or toward negative infinity, whereas this International Standard always rounds the result toward 0.

C.2.3 Clause [dcl.dcl]: declarations [diff.cpp03.dcl.dcl]

[dcl.spec]
Change: Remove auto as a storage class specifier
Rationale: New feature.
Effect on original feature: Valid C++ 2003 code that uses the keyword auto as a storage class specifier may be invalid in this International Standard. In this International Standard, auto indicates that the type of a variable is to be deduced from its initializer expression.

C.2.4 Clause [dcl.decl]: declarators [diff.cpp03.dcl.decl]

[dcl.init.list]
Change: Narrowing restrictions in aggregate initializers
Rationale: Catches bugs.
Effect on original feature: Valid C++ 2003 code may fail to compile in this International Standard. For example, the following code is valid in C++ 2003 but invalid in this International Standard because double to int is a narrowing conversion:

int x[] = { 2.0 };

C.2.5 Clause [special]: special member functions [diff.cpp03.special]

[class.ctor], [class.dtor], [class.copy]
Change: Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed.
Rationale: Improves template argument deduction failure.
Effect on original feature: A valid C++ 2003 program that uses one of these special member functions in a context where the definition is not required (e.g., in an expression that is not potentially evaluated) becomes ill-formed.

[class.dtor] (destructors)
Change: User-declared destructors have an implicit exception specification.
Rationale: Clarification of destructor requirements.
Effect on original feature: Valid C++ 2003 code may execute differently in this International Standard. In particular, destructors that throw exceptions will call std::terminate() (without calling std::unexpected()) if their exception specification is noexcept or noexcept(true). For a throwing virtual destructor of a derived class, std::terminate() can be avoided only if the base class virtual destructor has an exception specification that is not noexcept and not noexcept(true).

C.2.6 Clause [temp]: templates [diff.cpp03.temp]

[temp.param]
Change: Remove export
Rationale: No implementation consensus.
Effect on original feature: A valid C++ 2003 declaration containing export is ill-formed in this International Standard.

[temp.arg]
Change: Remove whitespace requirement for nested closing template right angle brackets
Rationale: Considered a persistent but minor annoyance. Template aliases representing nonclass types would exacerbate whitespace issues.
Effect on original feature: Change to semantics of well-defined expression. A valid C++ 2003 expression containing a right angle bracket (“>”) followed immediately by another right angle bracket may now be treated as closing two templates. For example, the following code is valid in C++ 2003 because “>>” is a right-shift operator, but invalid in this International Standard because “>>” closes two templates.

template <class T> struct X { };
template <int N> struct Y { };
X< Y< 1 >> 2 > > x;

[temp.dep.candidate]
Change: Allow dependent calls of functions with internal linkage
Rationale: Overly constrained, simplify overload resolution rules.
Effect on original feature: A valid C++ 2003 program could get a different result than this International Standard.

C.2.7 Clause [library]: library introduction [diff.cpp03.library]

[library][thread]
Change: New reserved identifiers
Rationale: Required by new features.
Effect on original feature: Valid C++ 2003 code that uses any identifiers added to the C++ standard library by this International Standard may fail to compile or produce different results in This International Standard. A comprehensive list of identifiers used by the C++ standard library can be found in the Index of Library Names in this International Standard.

[headers]
Change: New headers
Rationale: New functionality.
Effect on original feature: The following C++ headers are new: <array>, <atomic>, <chrono>, <codecvt>, <condition_variable>, <forward_list>, <future>, <initializer_list>, <mutex>, <random>, <ratio>, <regex>, <scoped_allocator>, <system_error>, <thread>, <tuple>, <typeindex>, <type_traits>,
<unordered_map>, and <unordered_set>. In addition the following C compatibility headers are new: <ccomplex>, <cfenv>, <cinttypes>, <cstdalign>, <cstdbool>, <cstdint>, <ctgmath>, and <cuchar>. Valid C++ 2003 code that #includes headers with these names may be invalid in this International Standard.

[swappable.requirements]
Effect on original feature: Function swap moved to a different header
Rationale: Remove dependency on <algorithm> for swap.
Effect on original feature: Valid C++ 2003 code that has been compiled expecting swap to be in <algorithm> may have to instead include <utility>.

[namespace.posix]
Change: New reserved namespace
Rationale: New functionality.
Effect on original feature: The global namespace posix is now reserved for standardization. Valid C++ 2003 code that uses a top-level namespace posix may be invalid in this International Standard.

[res.on.macro.definitions]
Change: Additional restrictions on macro names
Rationale: Avoid hard to diagnose or non-portable constructs.
Effect on original feature: Names of attribute identifiers may not be used as macro names. Valid C++ 2003 code that defines override, final, carries_dependency, or noreturn as macros is invalid in this International Standard.

C.2.8 Clause [language.support]: language support library [diff.cpp03.language.support]

[new.delete.single]
Change: Linking new and delete operators
Rationale: The two throwing single-object signatures of operator new and operator delete are now specified to form the base functionality for the other operators. This clarifies that replacing just these two signatures changes others, even if they are not explicitly changed.
Effect on original feature: Valid C++ 2003 code that replaces global new or delete operators may execute differently in this International Standard. For example, the following program should write "custom deallocation" twice, once for the single-object delete and once for the array delete.

#include <cstdio>
#include <cstdlib>
#include <new>

void* operator new(std::size_t size) throw(std::bad_alloc) {
  return std::malloc(size);
}

void operator delete(void* ptr) throw() {
  std::puts("custom deallocation");
  std::free(ptr);
}

int main() {
  int* i = new int;
  delete i;                     // single-object delete
  int* a = new int[3];
  delete [] a;                  // array delete
  return 0;
}

[new.delete.single]
Change: operator new may throw exceptions other than std::bad_alloc
Rationale: Consistent application of noexcept.
Effect on original feature: Valid C++ 2003 code that assumes that global operator new only throws std::bad_alloc may execute differently in this International Standard.

C.2.9 Clause [diagnostics]: diagnostics library [diff.cpp03.diagnostics]

[errno]
Change: Thread-local error numbers
Rationale: Support for new thread facilities.
Effect on original feature: Valid but implementation-specific C++ 2003 code that relies on errno being the same across threads may change behavior in this International Standard.

C.2.10 Clause [utilities]: general utilities library [diff.cpp03.utilities]

[util.dynamic.safety]
Change: Minimal support for garbage-collected regions
Rationale: Required by new feature.
Effect on original feature: Valid C++ 2003 code, compiled without traceable pointer support, that interacts with newer C++ code using regions declared reachable may have different runtime behavior.

[refwrap], [arithmetic.operations], [comparisons], [logical.operations], [bitwise.operations], [negators]
Change: Standard function object types no longer derived from std::unary_function or std::binary_function
Rationale: Superseded by new feature.
Effect on original feature: Valid C++ 2003 code that depends on function object types being derived from unary_function or binary_function will execute differently in this International Standard.

C.2.11 Clause [strings]: strings library [diff.cpp03.strings]

[string.classes]
Change: basic_string requirements no longer allow reference-counted strings
Rationale: Invalidation is subtly different with reference-counted strings. This change regularizes behavior for this International Standard.
Effect on original feature: Valid C++ 2003 code may execute differently in this International Standard.

[string.require]
Change: Loosen basic_string invalidation rules
Rationale: Allow small-string optimization.
Effect on original feature: Valid C++ 2003 code may execute differently in this International Standard. Some const member functions, such as data and c_str, no longer invalidate iterators.

C.2.12 Clause [containers]: containers library [diff.cpp03.containers]

[container.requirements]
Change: Complexity of size() member functions now constant
Rationale: Lack of specification of complexity of size() resulted in divergent implementations with inconsistent performance characteristics.
Effect on original feature: Some container implementations that conform to C++ 2003 may not conform to the specified size() requirements in this International Standard. Adjusting containers such as std::list to the stricter requirements may require incompatible changes.

[container.requirements]
Change: Requirements change: relaxation
Rationale: Clarification.
Effect on original feature: Valid C++ 2003 code that attempts to meet the specified container requirements may now be over-specified. Code that attempted to be portable across containers may need to be adjusted as follows:

  • not all containers provide size(); use empty() instead of size() == 0;

  • not all containers are empty after construction (array);

  • not all containers have constant complexity for swap() (array).

[container.requirements]
Change: Requirements change: default constructible
Rationale: Clarification of container requirements.
Effect on original feature: Valid C++ 2003 code that attempts to explicitly instantiate a container using a user-defined type with no default constructor may fail to compile.

[sequence.reqmts], [associative.reqmts]
Change: Signature changes: from void return types
Rationale: Old signature threw away useful information that may be expensive to recalculate.
Effect on original feature: The following member functions have changed:

  • erase(iter) for set, multiset, map, multimap

  • erase(begin, end) for set, multiset, map, multimap

  • insert(pos, num, val) for vector, deque, list, forward_list

  • insert(pos, beg, end) for vector, deque, list, forward_list

Valid C++ 2003 code that relies on these functions returning void (e.g., code that creates a pointer to member function that points to one of these functions) will fail to compile with this International Standard.

[sequence.reqmts], [associative.reqmts]
Change: Signature changes: from iterator to const_iterator parameters
Rationale: Overspecification. Effects: The signatures of the following member functions changed from taking an iterator to taking a const_iterator:

  • insert(iter, val) for vector, deque, list, set, multiset, map, multimap

  • insert(pos, beg, end) for vector, deque, list, forward_list

  • erase(iter) for set, multiset, map, multimap

  • erase(begin, end) for set, multiset, map, multimap

  • all forms of list::splice

  • all forms of list::merge

Valid C++ 2003 code that uses these functions may fail to compile with this International Standard.

[sequence.reqmts], [associative.reqmts]
Change: Signature changes: resize
Rationale: Performance, compatibility with move semantics.
Effect on original feature: For vector, deque, and list the fill value passed to resize is now passed by reference instead of by value, and an additional overload of resize has been added. Valid C++ 2003 code that uses this function may fail to compile with this International Standard.

C.2.13 Clause [algorithms]: algorithms library [diff.cpp03.algorithms]

[algorithms.general]
Change: Result state of inputs after application of some algorithms
Rationale: Required by new feature.
Effect on original feature: A valid C++ 2003 program may detect that an object with a valid but unspecified state has a different valid but unspecified state with this International Standard. For example, std::remove and std::remove_if may leave the tail of the input sequence with a different set of values than previously.

C.2.14 Clause [numerics]: numerics library [diff.cpp03.numerics]

[complex.numbers]
Change: Specified representation of complex numbers
Rationale: Compatibility with C99.
Effect on original feature: Valid C++ 2003 code that uses implementation-specific knowledge about the binary representation of the required template specializations of std::complex may not be compatible with this International Standard.

C.2.15 Clause [input.output]: Input/output library [diff.cpp03.input.output]

[istream::sentry], [ostream::sentry], [iostate.flags]
Change: Specify use of explicit in existing boolean conversion operators
Rationale: Clarify intentions, avoid workarounds.
Effect on original feature: Valid C++ 2003 code that relies on implicit boolean conversions will fail to compile with this International Standard. Such conversions occur in the following conditions:

  • passing a value to a function that takes an argument of type bool;

  • using operator== to compare to false or true;

  • returning a value from a function with a return type of bool;

  • initializing members of type bool via aggregate initialization;

  • initializing a const bool& which would bind to a temporary.

[ios::failure]
Change: Change base class of std::ios_base::failure
Rationale: More detailed error messages.
Effect on original feature: std::ios_base::failure is no longer derived directly from std::exception, but is now derived from std::system_error, which in turn is derived from std::runtime_error. Valid C++ 2003 code that assumes that std::ios_base::failure is derived directly from std::exception may execute differently in this International Standard.

[ios.base]
Change: Flag types in std::ios_base are now bitmasks with values defined as constexpr static members
Rationale: Required for new features.
Effect on original feature: Valid C++ 2003 code that relies on std::ios_base flag types being represented as std::bitset or as an integer type may fail to compile with this International Standard. For example:

#include <iostream>

int main() {
  int flag = std::ios_base::hex;
  std::cout.setf(flag);         // error: setf does not take argument of type int
  return 0;
}

C.3 C standard library [diff.library]

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 Standard C library noted in other subclauses ([headers], [support.types], [c.strings]).

The C++ standard library provides 57 standard macros from the C library, as shown in Table [tab:diff.standard.macros].

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

The C++ standard library provides 57 standard values from the C library, as shown in Table [tab:diff.standard.values].

Table 150 — 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 USRT_MAX
DBL_MIN FLT_RADIX LDBL_MIN_EXP
DBL_MIN_10_EXP FLT_ROUNDS LONG_MAX
DBL_MIN_EXP INT_MAX LONG_MIN

The C++ standard library provides 20 standard types from the C library, as shown in Table [tab:diff.standard.types].

Table 151 — Standard types
clock_t ldiv_t size_t <cstdio> va_list
div_t mbstate_t size_t <cstdlib> wctrans_t
FILE ptrdiff_t size_t <cstring> wctype_t
fpos_t sig_atomic_t size_t <ctime> wint_t <cwchar>
jmp_buf size_t <cstddef> time_t wint_t <cwctype>

The C++ standard library provides 2 standard structs from the C library, as shown in Table [tab:diff.standard.structs].

Table 152 — Standard structs
lconv tm

The C++ standard library provides 209 standard functions from the C library, as shown in Table [tab:diff.standard.functions].

Table 153 — 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.3.1 Modifications to headers [diff.mods.to.headers]

For compatibility with the Standard C library, the C++ standard library provides the 18 C headers ([depr.c.headers]), but their use is deprecated in C++.

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

C.3.2.1 Types char16_t and char32_t [diff.char16]

The types char16_t and char32_t are distinct types rather than typedefs to existing integral types.

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

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> ([c.strings]).

C.3.2.3 Header <iso646.h> [diff.header.iso646.h]

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

C.3.2.4 Macro NULL [diff.null]

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 ([support.types]).

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

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

[c.strings] describes the changes.

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

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

[support.start.term] describes the changes.

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

[support.runtime] describes the changes.

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

The macro offsetof, defined in <cstddef>, accepts a restricted set of type arguments in this International Standard. [support.types] describes the change.

C.3.4.2 Memory allocation functions [diff.malloc]

The functions calloc, malloc, and realloc are restricted in this International Standard. [c.malloc] describes the changes.