Annex C (informative) Compatibility [diff]

C.6 C++ and ISO C++ 2003 [diff.cpp03]

C.6.1 General [diff.cpp03.general]

Subclause [diff.cpp03] lists the differences between C++ and ISO C++ 2003 (ISO/IEC 14882:2003, Programming Languages — C++), in addition to those listed above, by the chapters of this document.

C.6.2 [lex]: lexical conventions [diff.cpp03.lex]

Affected subclause: [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 revision of C++.
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"
Affected subclause: [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 revision of C++.
For example: #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 revision of C++, #1 consists of a single preprocessing token, so the macro is not expanded.
Affected subclause: [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 revision of C++.
Affected subclause: [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.6.3 [expr]: expressions [diff.cpp03.expr]

Affected subclause: [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 revision of C++.
For example: void f(void *); // #1 void f(...); // #2 template<int N> void g() { f(0*N); // calls #2; used to call #1 }
Affected subclause: [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 revision of C++ always rounds the result toward 0.
Affected subclause: [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 revision of C++.
For example: 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.6.4 [dcl.dcl]: declarations [diff.cpp03.dcl.dcl]

Affected subclause: [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 revision of C++.
In this revision of C++, auto indicates that the type of a variable is to be deduced from its initializer expression.
Affected subclause: [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 revision of C++.
For example: int x[] = { 2.0 };
This code is valid in C++ 2003 but invalid in this revision of C++ because double to int is a narrowing conversion.
Affected subclause: [dcl.link]
Change: Names declared in an anonymous namespace changed from external linkage to internal linkage; language linkage applies to names with external linkage only.

Rationale: Alignment with user expectations.

Effect on original feature: Valid C++ 2003 code may violate the one-definition rule ([basic.def.odr]) in this revision of C++.
For example: namespace { extern "C" { extern int x; } } // #1, previously external linkage and C language linkage, // now internal linkage and C++ language linkage namespace A { extern "C" int x = 42; } // #2, external linkage and C language linkage int main(void) { return x; }
This code is valid in C++ 2003, but #2 is not a definition for #1 in this revision of C++, violating the one-definition rule.

C.6.5 [class]: classes [diff.cpp03.class]

Affected subclauses: [class.default.ctor], [class.dtor], [class.copy.ctor], and [class.copy.assign]
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.
Affected subclause: [class.dtor]
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 revision of C++.
In particular, destructors that throw exceptions will call std​::​terminate (without calling std​::​unexpected) if their exception specification is non-throwing.

C.6.6 [temp]: templates [diff.cpp03.temp]

Affected subclause: [temp.param]
Change: Repurpose export for modules ([module], [cpp.module], [cpp.import]).

Rationale: No implementation consensus for the C++ 2003 meaning of export.

Effect on original feature: A valid C++ 2003 program containing export is ill-formed in this revision of C++.
Affected subclause: [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: template <class T> struct X { }; template <int N> struct Y { }; X< Y< 1 >> 2 > > x;
This code is valid in C++ 2003 because “>>” is a right-shift operator, but invalid in this revision of C++ because “>>” closes two templates.
Affected subclause: [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 can get a different result in this revision of C++.

C.6.7 [library]: library introduction [diff.cpp03.library]

Affected: [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 later revisions of C++ may fail to compile or produce different results in this revision of C++.
A comprehensive list of identifiers used by the C++ standard library can be found in the Index of Library Names in this document.
Affected subclause: [headers]
Change: New headers.

Rationale: New functionality.

In addition the following C compatibility headers are new: <cfenv>, <cinttypes>, <cstdint>, and <cuchar>.
Valid C++ 2003 code that #includes headers with these names may be invalid in this revision of C++.
Affected subclause: [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>.
Affected subclause: [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 revision of C++.
Affected subclause: [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 revision of C++.

C.6.8 [support]: language support library [diff.cpp03.language.support]

Affected subclause: [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 revision of C++.
Valid C++ 2003 code that replaces the global replaceable operator new is ill-formed in this revision of C++, because the exception specification of throw(std​::​bad_alloc) was removed.

C.6.9 [diagnostics]: diagnostics library [diff.cpp03.diagnostics]

Affected subclause: [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 revision of C++.

C.6.10 [utilities]: general utilities library [diff.cpp03.utilities]

Affected subclauses: [refwrap], [arithmetic.operations], [comparisons], [logical.operations], and [bitwise.operations]
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 revision of C++.

C.6.11 [strings]: strings library [diff.cpp03.strings]

Affected subclause: [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.

Effect on original feature: Valid C++ 2003 code may execute differently in this revision of C++.
Affected subclause: [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 revision of C++.
Some const member functions, such as data and c_str, no longer invalidate iterators.

C.6.12 [containers]: containers library [diff.cpp03.containers]

Affected subclause: [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 revision of C++.
Adjusting containers such as std​::​list to the stricter requirements may require incompatible changes.
Affected subclause: [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).
Affected subclause: [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.
Affected subclauses: [sequence.reqmts] and [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 revision of C++.
Affected subclauses: [sequence.reqmts] and [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 revision of C++.
Affected subclauses: [sequence.reqmts] and [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 revision of C++.

C.6.13 [algorithms]: algorithms library [diff.cpp03.algorithms]

Affected subclause: [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 revision of C++.
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.6.14 [numerics]: numerics library [diff.cpp03.numerics]

Affected subclause: [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 revision of C++.

C.6.15 [localization]: localization library [diff.cpp03.locale]

Affected subclause: [facet.num.get.virtuals]
Change: The num_get facet recognizes hexadecimal floating point values.

Rationale: Required by new feature.

Effect on original feature: Valid C++ 2003 code may have different behavior in this revision of C++.

C.6.16 [input.output]: input/output library [diff.cpp03.input.output]

Affected subclauses: [istream.sentry], [ostream.sentry], and [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 revision of C++.
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 object.
Affected subclause: [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 revision of C++.
Affected subclause: [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 revision of C++.
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 }