[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.syn#header:%3cshared_mutex%3e "32.6.3 Header 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)