Annex C (informative) Compatibility [diff]

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 token, so the macro is not expanded.
[lex.key]
Change: New keywords.

Rationale: Required for new features.

Effect on original feature: Added to Table 5, 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 [conv]: standard conversions [diff.cpp03.conv]

[conv.ptr]
Change: Only literals are integer null pointer constants.

Rationale: Removing surprising interactions with templates and constant expressions.

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:
void f(void *);  // #1
void f(...);     // #2
template<int N> void g() {
  f(0*N);        // calls #2; used to call #1
}

C.2.3 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.
[expr.log.and]
Change:&& is valid in a type-name.

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:
bool b1 = new int && false;           // previously false, now ill-formed
struct S { operator int(); };
bool b2 = &S::operator int && false;  // previously false, now ill-formed

C.2.4 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.5 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.6 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 non-throwing.

C.2.7 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 non-class 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.8 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.9 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
}
[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.10 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.11 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], [depr.negators]
Change: Standard function object types no longer derived from std​::​unary_­function or std​::​binary_­function.

Rationale: Superseded by new feature; unary_­function and binary_­function are no longer defined.

Effect on original feature: Valid C++ 2003 code that depends on function object types being derived from unary_­function or binary_­function may fail to compile in this International Standard.

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

Effect on original feature: 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(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.14 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.15 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.16 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 functions.

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
}