[diff.cpp11]

# Annex C (informative) Compatibility [[diff]](./#diff)

## C.5 C++ and ISO C++ 2011 [diff.cpp11]

### [C.5.1](#general) General [[diff.cpp11.general]](diff.cpp11.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1964)

Subclause [diff.cpp11] lists the differences between C++ and
ISO C++ 2011,
in addition to those listed above,
by the chapters of this document[.](#general-1.sentence-1)

### [C.5.2](#lex) [[lex]](lex "5 Lexical conventions"): lexical conventions [[diff.cpp11.lex]](diff.cpp11.lex)

[1](#lex-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1973)

**Affected subclause:** [[lex.ppnumber]](lex.ppnumber)  


**Change:** [*pp-number*](lex.ppnumber#nt:pp-number "5.7 Preprocessing numbers [lex.ppnumber]") can contain one or more single quotes[.](#lex-1.sentence-1)

  


**Rationale:** Necessary to enable single quotes as digit separators[.](#lex-1.sentence-2)

  


**Effect on original feature:** Valid C++ 2011 code may fail to compile or may change meaning in this
revision of C++[.](#lex-1.sentence-3)

For example, the following code is valid both in C++ 2011 and in
this revision of C++, but the macro invocation produces different outcomes
because the single quotes delimit a [*character-literal*](lex.ccon#nt:character-literal "5.13.3 Character literals [lex.ccon]") in C++ 2011, whereas they are digit
separators in this revision of C++[.](#lex-1.sentence-4)

[*Example [1](#lex-example-1)*: #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 revision of C++ â *end example*]

### [C.5.3](#basic) [[basic]](basic "6 Basics"): basics [[diff.cpp11.basic]](diff.cpp11.basic)

[1](#basic-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1995)

**Affected subclause:** [[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation)  


**Change:** New usual (non-placement) deallocator[.](#basic-1.sentence-1)

  


**Rationale:** Required for sized deallocation[.](#basic-1.sentence-2)

  


**Effect on original feature:** Valid C++ 2011 code can 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 revision of C++, however, the declaration of operator delete might match a predefined usual (non-placement)operator delete ([[basic.stc.dynamic]](basic.stc.dynamic "6.8.6.5 Dynamic storage duration"))[.](#basic-1.sentence-4)

If so, the
program is ill-formed, as it was for class member allocation functions and
deallocation functions ([[expr.new]](expr.new "7.6.2.8 New"))[.](#basic-1.sentence-5)

### [C.5.4](#expr) [[expr]](expr "7 Expressions"): expressions [[diff.cpp11.expr]](diff.cpp11.expr)

[1](#expr-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L2015)

**Affected subclause:** [[expr.cond]](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[.](#expr-1.sentence-1)

  


**Rationale:** Formerly mandated conversions ([lvalue-to-rvalue](conv.lval "7.3.2 Lvalue-to-rvalue conversion [conv.lval]"),[array-to-pointer](conv.array "7.3.3 Array-to-pointer conversion [conv.array]"), and [function-to-pointer](conv.func "7.3.4 Function-to-pointer conversion [conv.func]") standard conversions), especially the creation of the temporary due to
lvalue-to-rvalue conversion, were considered gratuitous and surprising[.](#expr-1.sentence-2)

  


**Effect on original feature:** Valid C++ 2011 code that relies on the conversions may behave differently
in this revision of C++[.](#expr-1.sentence-3)

[*Example [1](#expr-example-1)*: 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[.](#expr-1.sentence-4)

In this revision of C++,
it returns 2[.](#expr-1.sentence-5)

sizeof(true ? "" : throw 0)

In C++ 2011, the expression yields sizeof(const char*)[.](#expr-1.sentence-6)

In this
revision of C++, it yields sizeof(const char[1])[.](#expr-1.sentence-7)

â *end example*]

### [C.5.5](#dcl.dcl) [[dcl]](dcl "9 Declarations"): declarations [[diff.cpp11.dcl.dcl]](diff.cpp11.dcl.dcl)

[1](#dcl.dcl-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L2050)

**Affected subclause:** [[dcl.constexpr]](dcl.constexpr)  


**Change:** constexpr non-static member functions are not implicitlyconst member functions[.](#dcl.dcl-1.sentence-1)

  


**Rationale:** Necessary to allow constexpr member functions to mutate
the object[.](#dcl.dcl-1.sentence-2)

  


**Effect on original feature:** Valid C++ 2011 code may fail to compile in this revision of C++[.](#dcl.dcl-1.sentence-3)

[*Example [1](#dcl.dcl-example-1)*: struct S {constexpr const int &f(); int &f();};

This code is valid in C++ 2011
but invalid in this revision of C++ because it declares the same member
function twice with different return types[.](#dcl.dcl-1.sentence-4)

â *end example*]

[2](#dcl.dcl-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L2071)

**Affected subclause:** [[dcl.init.aggr]](dcl.init.aggr)  


**Change:** Classes with default member initializers can be aggregates[.](#dcl.dcl-2.sentence-1)

  


**Rationale:** Necessary to allow default member initializers to be used
by aggregate initialization[.](#dcl.dcl-2.sentence-2)

  


**Effect on original feature:** Valid C++ 2011 code may fail to compile or may change meaning in this revision of C++[.](#dcl.dcl-2.sentence-3)

[*Example [2](#dcl.dcl-example-2)*: 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 revision of C++ â *end example*]

### [C.5.6](#library) [[library]](library "16 Library introduction"): library introduction [[diff.cpp11.library]](diff.cpp11.library)

[1](#library-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L2096)

**Affected subclause:** [[headers]](headers)  


**Change:** New header[.](#library-1.sentence-1)

  


**Rationale:** New functionality[.](#library-1.sentence-2)

  


**Effect on original feature:** The C++ header [<shared_mutex>](shared.mutex.syn#header:%3cshared_mutex%3e "32.6.3 Header <shared_­mutex> synopsis [shared.mutex.syn]") is new[.](#library-1.sentence-3)

Valid C++ 2011 code that #includes a header with that name may be
invalid in this revision of C++[.](#library-1.sentence-4)

### [C.5.7](#input.output) [[input.output]](input.output "31 Input/output library"): input/output library [[diff.cpp11.input.output]](diff.cpp11.input.output)

[1](#input.output-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L2108)

**Affected subclause:** [[c.files]](c.files)  


**Change:** gets is not defined[.](#input.output-1.sentence-1)

  


**Rationale:** Use of gets is considered dangerous[.](#input.output-1.sentence-2)

  


**Effect on original feature:** Valid C++ 2011 code that uses the gets function may fail to compile
in this revision of C++[.](#input.output-1.sentence-3)
