497 lines
18 KiB
Markdown
497 lines
18 KiB
Markdown
[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<int>, now intauto x2{1, 2}; // was std::initializer_list<int>, 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<class T> 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<typename T> 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>(long),// which called A(int) due to substitution failure// in A<long>(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 <int N> struct A;template <typename T, T N> int foo(A<N> *) = 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>](any.synop#header:%3cany%3e "22.7.2 Header <any> synopsis [any.synop]"),[<charconv>](charconv.syn#header:%3ccharconv%3e "28.2.1 Header <charconv> synopsis [charconv.syn]"),[<execution>](execution.syn#header:%3cexecution%3e "33.4 Header <execution> synopsis [execution.syn]"),[<filesystem>](fs.filesystem.syn#header:%3cfilesystem%3e "31.12.4 Header <filesystem> synopsis [fs.filesystem.syn]"),[<memory_resource>](mem.res.syn#header:%3cmemory_resource%3e "20.5.1 Header <memory_resource> synopsis [mem.res.syn]"),[<optional>](optional.syn#header:%3coptional%3e "22.5.2 Header <optional> synopsis [optional.syn]"),
|
||
|
||
[<string_view>](string.view.synop#header:%3cstring_view%3e "27.3.2 Header <string_view> synopsis [string.view.synop]"),
|
||
and[<variant>](variant.syn#header:%3cvariant%3e "22.6.2 Header <variant> 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<T[]> and shared_ptr<T[N]>[.](#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 <memory> std::unique_ptr<int[]> arr(new int[1]);
|
||
std::shared_ptr<int> 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 <set>struct compare{bool operator()(int a, int b){return a < b; }};
|
||
|
||
int main() {const std::set<int, compare> 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)
|