This subclause lists the differences between C++ and ISO C++ 2011 (ISO/IEC 14882:2011, Programming Languages — C++), by the chapters of this document.
[lex.ppnumber]
Change: pp-number can contain one or more single quotes.
Rationale: Necessary to enable single quotes as digit separators.
Effect on original feature: Valid C++ 2011 code may fail to compile or may change meaning in this
International Standard. For example, the following code is valid both in C++ 2011 and in
this International Standard, but the macro invocation produces different outcomes
because the single quotes delimit a character literal in C++ 2011, whereas they are digit
separators in this International Standard:
#define M(x, ...) __VA_ARGS__ int x[2] = { M(1'2,3'4, 5) }; // int x[2] = { 5 }; — C++ 2011 // int x[2] = { 3'4, 5 }; — this International Standard
[basic.stc.dynamic.deallocation]
Change: New usual (non-placement) deallocator.
Rationale: Required for sized deallocation.
Effect on original feature: Valid C++ 2011 code could declare a global placement allocation function and
deallocation function as follows:
void* operator new(std::size_t, std::size_t); void operator delete(void*, std::size_t) noexcept;
In this International Standard, however, the declaration of operator delete might match a predefined usual (non-placement) operator delete ([basic.stc.dynamic]). If so, the program is ill-formed, as it was for class member allocation functions and deallocation functions ([expr.new]).
[expr.cond]
Change: A conditional expression with a throw expression as its second or third
operand keeps the type and value category of the other operand.
Rationale: Formerly mandated conversions (lvalue-to-rvalue,
array-to-pointer, and function-to-pointer
standard conversions), especially the creation of the temporary due to
lvalue-to-rvalue conversion, were considered gratuitous and surprising.
Effect on original feature: Valid C++ 2011 code that relies on the conversions may behave differently
in this International Standard:
struct S { int x = 1; void mf() { x = 2; } }; int f(bool cond) { S s; (cond ? s : throw 0).mf(); return s.x; }
In C++ 2011, f(true) returns 1. In this International Standard, it returns 2.
sizeof(true ? "" : throw 0)
In C++ 2011, the expression yields sizeof(const char*). In this International Standard, it yields sizeof(const char[1]).
[dcl.constexpr]
Change: constexpr non-static member functions are not implicitly
const member functions.
Rationale: Necessary to allow constexpr member functions to mutate
the object.
Effect on original feature:
Valid C++ 2011 code may fail to compile in this International Standard.
For example, the following code is valid in C++ 2011
but invalid in this International Standard because it declares the same member
function twice with different return types:
struct S { constexpr const int &f(); int &f(); };
[dcl.init.aggr]
Change: Classes with default member initializers can be aggregates.
Rationale: Necessary to allow default member initializers to be used
by aggregate initialization.
Effect on original feature:
Valid C++ 2011 code may fail to compile or may change meaning in this International Standard.
struct S { // Aggregate in C++ 2014 onwards. int m = 1; }; struct X { operator int(); operator S(); }; X a{}; S b{a}; // uses copy constructor in C++ 2011, // performs aggregate initialization in this International Standard
[headers]
Change: New header.
Rationale: New functionality.
Effect on original feature:
The C++ header <shared_mutex> is new.
Valid C++ 2011 code that #includes a header with that name may be
invalid in this International Standard.
[c.files]
Change: gets is not defined.
Rationale: Use of gets is considered dangerous.
Effect on original feature:
Valid C++ 2011 code that uses the gets function may fail to compile
in this International Standard.