[diff.cpp14] # Annex C (informative) Compatibility [[diff]](./#diff) ## C.4 C++ and ISO C++ 2014 [diff.cpp14] ### [C.4.1](#general) General [[diff.cpp14.general]](diff.cpp14.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1594) Subclause [diff.cpp14] lists the differences between C++ and ISO C++ 2014, in addition to those listed above, by the chapters of this document[.](#general-1.sentence-1) ### [C.4.2](#lex) [[lex]](lex "5 Lexical conventions"): lexical conventions [[diff.cpp14.lex]](diff.cpp14.lex) [1](#lex-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1603) **Affected subclause:** [[lex.phases]](lex.phases) **Change:** Removal of trigraph support as a required feature[.](#lex-1.sentence-1) **Rationale:** Prevents accidental uses of trigraphs in non-raw string literals and comments[.](#lex-1.sentence-2) **Effect on original feature:** Valid C++ 2014 code that uses trigraphs may not be valid or may have different semantics in this revision of C++[.](#lex-1.sentence-3) Implementations may choose to translate trigraphs as specified in C++ 2014 if they appear outside of a raw string literal, as part of theimplementation-defined mapping from input source file characters to the translation character set[.](#lex-1.sentence-4) [2](#lex-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1618) **Affected subclause:** [[lex.ppnumber]](lex.ppnumber) **Change:** [*pp-number*](lex.ppnumber#nt:pp-number "5.7 Preprocessing numbers [lex.ppnumber]") can contain p [*sign*](lex.fcon#nt:sign "5.13.4 Floating-point literals [lex.fcon]") andP [*sign*](lex.fcon#nt:sign "5.13.4 Floating-point literals [lex.fcon]")[.](#lex-2.sentence-1) **Rationale:** Necessary to enable [*hexadecimal-floating-point-literal*](lex.fcon#nt:hexadecimal-floating-point-literal "5.13.4 Floating-point literals [lex.fcon]")*s*[.](#lex-2.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or produce different results in this revision of C++[.](#lex-2.sentence-3) Specifically, character sequences like 0p+0 and 0e1_p+0 are three separate tokens each in C++ 2014, but one single token in this revision of C++[.](#lex-2.sentence-4) [*Example [1](#lex-example-1)*: #define F(a) b ## aint b0p = F(0p+0); // ill-formed; equivalent to “int b0p = b0p + 0;'' in C++ 2014 — *end example*] ### [C.4.3](#expr) [[expr]](expr "7 Expressions"): expressions [[diff.cpp14.expr]](diff.cpp14.expr) [1](#expr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1638) **Affected subclauses:** [[expr.post.incr]](expr.post.incr) and [[expr.pre.incr]](expr.pre.incr) **Change:** Remove increment operator with bool operand[.](#expr-1.sentence-1) **Rationale:** Obsolete feature with occasionally surprising semantics[.](#expr-1.sentence-2) **Effect on original feature:** A valid C++ 2014 expression utilizing the increment operator on a bool lvalue is ill-formed in this revision of C++[.](#expr-1.sentence-3) [2](#expr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1647) **Affected subclauses:** [[expr.new]](expr.new) and [[expr.delete]](expr.delete) **Change:** Dynamic allocation mechanism for over-aligned types[.](#expr-2.sentence-1) **Rationale:** Simplify use of over-aligned types[.](#expr-2.sentence-2) **Effect on original feature:** In C++ 2014 code that uses a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]") to allocate an object with an over-aligned class type, where that class has no allocation functions of its own,​::​operator new(std​::​size_t) is used to allocate the memory[.](#expr-2.sentence-3) In this revision of C++,​::​operator new(std​::​size_t, std​::​align_val_t) is used instead[.](#expr-2.sentence-4) ### [C.4.4](#dcl.dcl) [[dcl]](dcl "9 Declarations"): declarations [[diff.cpp14.dcl.dcl]](diff.cpp14.dcl.dcl) [1](#dcl.dcl-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1664) **Affected subclause:** [[dcl.stc]](dcl.stc) **Change:** Removal of register [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2 Storage class specifiers [dcl.stc]")[.](#dcl.dcl-1.sentence-1) **Rationale:** Enable repurposing of deprecated keyword in future revisions of C++[.](#dcl.dcl-1.sentence-2) **Effect on original feature:** A valid C++ 2014 declaration utilizing the register[*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2 Storage class specifiers [dcl.stc]") is ill-formed in this revision of C++[.](#dcl.dcl-1.sentence-3) The specifier can simply be removed to retain the original meaning[.](#dcl.dcl-1.sentence-4) [2](#dcl.dcl-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1675) **Affected subclause:** [[dcl.spec.auto]](dcl.spec.auto) **Change:** auto deduction from [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")[.](#dcl.dcl-2.sentence-1) **Rationale:** More intuitive deduction behavior[.](#dcl.dcl-2.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or may change meaning in this revision of C++[.](#dcl.dcl-2.sentence-3) [*Example [1](#dcl.dcl-example-1)*: auto x1{1}; // was std​::​initializer_list, now intauto x2{1, 2}; // was std​::​initializer_list, now ill-formed — *end example*] [3](#dcl.dcl-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1690) **Affected subclause:** [[dcl.fct]](dcl.fct) **Change:** Make exception specifications be part of the type system[.](#dcl.dcl-3.sentence-1) **Rationale:** Improve type-safety[.](#dcl.dcl-3.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or change meaning in this revision of C++[.](#dcl.dcl-3.sentence-3) [*Example [2](#dcl.dcl-example-2)*: void g1() noexcept;void g2();template int f(T *, T *);int x = f(g1, g2); // ill-formed; previously well-formed — *end example*] [4](#dcl.dcl-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1707) **Affected subclause:** [[dcl.init.aggr]](dcl.init.aggr) **Change:** Definition of an aggregate is extended to apply to user-defined types with base classes[.](#dcl.dcl-4.sentence-1) **Rationale:** To increase convenience of aggregate initialization[.](#dcl.dcl-4.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or produce different results in this revision of C++; initialization from an empty initializer list will perform aggregate initialization instead of invoking a default constructor for the affected types[.](#dcl.dcl-4.sentence-3) [*Example [3](#dcl.dcl-example-3)*: struct derived;struct base {friend struct derived;private: base();};struct derived : base {}; derived d1{}; // error; the code was well-formed in C++ 2014 derived d2; // still OK — *end example*] ### [C.4.5](#class) [[class]](class "11 Classes"): classes [[diff.cpp14.class]](diff.cpp14.class) [1](#class-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1735) **Affected subclause:** [[class.inhctor.init]](class.inhctor.init) **Change:** Inheriting a constructor no longer injects a constructor into the derived class[.](#class-1.sentence-1) **Rationale:** Better interaction with other language features[.](#class-1.sentence-2) **Effect on original feature:** Valid C++ 2014 code that uses inheriting constructors may not be valid or may have different semantics[.](#class-1.sentence-3) A [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") that names a constructor now makes the corresponding base class constructors visible to initializations of the derived class rather than declaring additional derived class constructors[.](#class-1.sentence-4) [*Example [1](#class-example-1)*: struct A {template A(T, typename T::type = 0); A(int);};struct B : A {using A::A; B(int);}; B b(42L); // now calls B(int), used to call B(long),// which called A(int) due to substitution failure// in A(long). — *end example*] ### [C.4.6](#temp) [[temp]](temp "13 Templates"): templates [[diff.cpp14.temp]](diff.cpp14.temp) [1](#temp-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1764) **Affected subclause:** [[temp.deduct.type]](temp.deduct.type) **Change:** Allowance to deduce from the type of a constant template argument[.](#temp-1.sentence-1) **Rationale:** In combination with the ability to declare constant template arguments with placeholder types, allows partial specializations to decompose from the type deduced for the constant template argument[.](#temp-1.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or produce different results in this revision of C++[.](#temp-1.sentence-3) [*Example [1](#temp-example-1)*: template struct A;template int foo(A *) = delete;void foo(void *);void bar(A<0> *p) { foo(p); // ill-formed; previously well-formed} — *end example*] ### [C.4.7](#except) [[except]](except "14 Exception handling"): exception handling [[diff.cpp14.except]](diff.cpp14.except) [1](#except-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1788) **Affected subclause:** [[except.spec]](except.spec) **Change:** Remove dynamic exception specifications[.](#except-1.sentence-1) **Rationale:** Dynamic exception specifications were a deprecated feature that was complex and brittle in use[.](#except-1.sentence-2) They interacted badly with the type system, which became a more significant issue in this revision of C++ where (non-dynamic) exception specifications are part of the function type[.](#except-1.sentence-3) **Effect on original feature:** A valid C++ 2014 function declaration, member function declaration, function pointer declaration, or function reference declaration, if it has a potentially throwing dynamic exception specification, is rejected as ill-formed in this revision of C++[.](#except-1.sentence-4) Violating a non-throwing dynamic exception specification calls terminate rather than unexpected, and it is unspecified whether stack unwinding is performed prior to such a call[.](#except-1.sentence-5) ### [C.4.8](#library) [[library]](library "16 Library introduction"): library introduction [[diff.cpp14.library]](diff.cpp14.library) [1](#library-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1811) **Affected subclause:** [[headers]](headers) **Change:** New headers[.](#library-1.sentence-1) **Rationale:** New functionality[.](#library-1.sentence-2) **Effect on original feature:** The following C++ headers are new:[](any.synop#header:%3cany%3e "22.7.2 Header synopsis [any.synop]"),[](charconv.syn#header:%3ccharconv%3e "28.2.1 Header synopsis [charconv.syn]"),[](execution.syn#header:%3cexecution%3e "33.4 Header synopsis [execution.syn]"),[](fs.filesystem.syn#header:%3cfilesystem%3e "31.12.4 Header synopsis [fs.filesystem.syn]"),[](mem.res.syn#header:%3cmemory_resource%3e "20.5.1 Header synopsis [mem.res.syn]"),[](optional.syn#header:%3coptional%3e "22.5.2 Header synopsis [optional.syn]"), [](string.view.synop#header:%3cstring_view%3e "27.3.2 Header synopsis [string.view.synop]"), and[](variant.syn#header:%3cvariant%3e "22.6.2 Header synopsis [variant.syn]")[.](#library-1.sentence-4) Valid C++ 2014 code that #includes headers with these names may be invalid in this revision of C++[.](#library-1.sentence-5) [2](#library-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1830) **Affected subclause:** [[namespace.future]](namespace.future) **Change:** New reserved namespaces[.](#library-2.sentence-1) **Rationale:** Reserve namespaces for future revisions of the standard library that might otherwise be incompatible with existing programs[.](#library-2.sentence-2) **Effect on original feature:** The global namespaces std followed by an arbitrary sequence of [*digit*](lex.name#nt:digit "5.11 Identifiers [lex.name]")*s* ([[lex.name]](lex.name "5.11 Identifiers")) are reserved for future standardization[.](#library-2.sentence-3) Valid C++ 2014 code that uses such a top-level namespace, e.g., std2, may be invalid in this revision of C++[.](#library-2.sentence-4) ### [C.4.9](#utilities) [[utilities]](utilities "22 General utilities library"): general utilities library [[diff.cpp14.utilities]](diff.cpp14.utilities) [1](#utilities-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1845) **Affected subclause:** [[func.wrap]](func.wrap) **Change:** Constructors taking allocators removed[.](#utilities-1.sentence-1) **Rationale:** No implementation consensus[.](#utilities-1.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or may change meaning in this revision of C++[.](#utilities-1.sentence-3) Specifically, constructing a std​::​function with an allocator is ill-formed and uses-allocator construction will not pass an allocator to std​::​function constructors in this revision of C++[.](#utilities-1.sentence-4) [2](#utilities-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1856) **Affected subclause:** [[util.smartptr.shared]](util.smartptr.shared) **Change:** Different constraint on conversions from unique_ptr[.](#utilities-2.sentence-1) **Rationale:** Adding array support to shared_ptr, via the syntax shared_ptr and shared_ptr[.](#utilities-2.sentence-2) **Effect on original feature:** Valid C++ 2014 code may fail to compile or may change meaning in this revision of C++[.](#utilities-2.sentence-3) [*Example [1](#utilities-example-1)*: #include std::unique_ptr arr(new int[1]); std::shared_ptr ptr(std::move(arr)); // error: int(*)[] is not compatible with int* — *end example*] ### [C.4.10](#string) [[strings]](strings "27 Strings library"): strings library [[diff.cpp14.string]](diff.cpp14.string) [1](#string-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1875) **Affected subclause:** [[basic.string]](basic.string) **Change:** Non-const .data() member added[.](#string-1.sentence-1) **Rationale:** The lack of a non-const .data() differed from the similar member of std​::​vector[.](#string-1.sentence-2) This change regularizes behavior[.](#string-1.sentence-3) **Effect on original feature:** Overloaded functions which have differing code paths for char* and const char* arguments will execute differently when called with a non-const string's .data() member in this revision of C++[.](#string-1.sentence-4) [*Example [1](#string-example-1)*: int f(char *) = delete;int f(const char *); string s;int x = f(s.data()); // ill-formed; previously well-formed — *end example*] ### [C.4.11](#containers) [[containers]](containers "23 Containers library"): containers library [[diff.cpp14.containers]](diff.cpp14.containers) [1](#containers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1899) **Affected subclause:** [[associative.reqmts]](associative.reqmts) **Change:** Requirements change: **Rationale:** Increase portability, clarification of associative container requirements[.](#containers-1.sentence-2) **Effect on original feature:** Valid C++ 2014 code that attempts to use associative containers having a comparison object with non-const function call operator may fail to compile in this revision of C++[.](#containers-1.sentence-3) [*Example [1](#containers-example-1)*: #include struct compare{bool operator()(int a, int b){return a < b; }}; int main() {const std::set s; s.find(0);} — *end example*] ### [C.4.12](#depr) [[depr]](depr "Annex D (normative) Compatibility features"): compatibility features [[diff.cpp14.depr]](diff.cpp14.depr) [1](#depr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1930) **Change:** The class templatesauto_ptr,unary_function, andbinary_function, the function templatesrandom_shuffle, and the function templates (and their return types)ptr_fun,mem_fun,mem_fun_ref,bind1st, andbind2nd are not defined[.](#depr-1.sentence-1) **Rationale:** Superseded by new features[.](#depr-1.sentence-2) **Effect on original feature:** Valid C++ 2014 code that uses these class templates and function templates may fail to compile in this revision of C++[.](#depr-1.sentence-3) [2](#depr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1951) **Change:** Remove old iostreams members [depr.ios.members][.](#depr-2.sentence-1) **Rationale:** Redundant feature for compatibility with pre-standard code has served its time[.](#depr-2.sentence-2) **Effect on original feature:** A valid C++ 2014 program using these identifiers may be ill-formed in this revision of C++[.](#depr-2.sentence-3)