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 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;
}