[diff.cpp17]

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

## C.3 C++ and ISO C++ 2017 [diff.cpp17]

### [C.3.1](#general) General [[diff.cpp17.general]](diff.cpp17.general)

[1](#general-1)

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

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

### [C.3.2](#lex) [[lex]](lex "5 Lexical conventions"): lexical conventions [[diff.cpp17.lex]](diff.cpp17.lex)

[1](#lex-1)

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

**Affected subclauses:** [[lex.pptoken]](lex.pptoken), [[module.unit]](module.unit), [[module.import]](module.import), [[cpp.pre]](cpp.pre), [[cpp.module]](cpp.module), and [[cpp.import]](cpp.import)  


**Change:** New identifiers with special meaning[.](#lex-1.sentence-1)

  


**Rationale:** Required for new features[.](#lex-1.sentence-2)

  


**Effect on original feature:** Logical lines beginning withmodule or import may
be interpreted differently
in this revision of C++[.](#lex-1.sentence-3)

[*Example [1](#lex-example-1)*: class module {};module m1; // was variable declaration; now [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]")module *m2; // variable declarationclass import {};import j1; // was variable declaration; now [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")::import j2; // variable declaration â *end example*]

[2](#lex-2)

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

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


**Change:** [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") tokens are formed in more contexts[.](#lex-2.sentence-1)

  


**Rationale:** Required for new features[.](#lex-2.sentence-2)

  


**Effect on original feature:** When the identifier import is followed by a < character,
a [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") token may be formed[.](#lex-2.sentence-3)

[*Example [2](#lex-example-2)*: template<typename> class import {};import<int> f(); // ill-formed; previously well-formed::import<int> g(); // OK â *end example*]

[3](#lex-3)

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

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


**Change:** New keywords[.](#lex-3.sentence-1)

  


**Rationale:** Required for new features[.](#lex-3.sentence-2)

- [(3.1)](#lex-3.1)

  The char8_t keyword is added to differentiate
the types of ordinary and UTF-8 literals ([[lex.string]](lex.string "5.13.5 String literals"))[.](#lex-3.1.sentence-1)

- [(3.2)](#lex-3.2)

  The concept keyword is
added to enable the definition of concepts ([[temp.concept]](temp.concept "13.7.9 Concept definitions"))[.](#lex-3.2.sentence-1)

- [(3.3)](#lex-3.3)

  The consteval keyword is added to
declare immediate functions ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"))[.](#lex-3.3.sentence-1)

- [(3.4)](#lex-3.4)

  The constinit keyword is added to
prevent unintended dynamic initialization ([[dcl.constinit]](dcl.constinit "9.2.7 The constinit specifier"))[.](#lex-3.4.sentence-1)

- [(3.5)](#lex-3.5)

  The co_await, co_yield, and co_return keywords are added
to enable the definition of coroutines ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions"))[.](#lex-3.5.sentence-1)

- [(3.6)](#lex-3.6)

  The requires keyword is added
to introduce constraints through a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble"))
or a [*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") ([[expr.prim.req]](expr.prim.req "7.5.8 Requires expressions"))[.](#lex-3.6.sentence-1)

**Effect on original feature:** Valid C++ 2017 code usingchar8_t,concept,consteval,constinit,co_await, co_yield, co_return,
or requires as an identifier is not valid in this revision of C++[.](#lex-3.sentence-3)

[4](#lex-4)

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

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


**Change:** New operator <=>[.](#lex-4.sentence-1)

  


**Rationale:** Necessary for new functionality[.](#lex-4.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code that contains a <= token
immediately followed by a > token
may be ill-formed or have different semantics in this revision of C++[.](#lex-4.sentence-3)

[*Example [3](#lex-example-3)*: namespace N {struct X {}; bool operator<=(X, X); template<bool(X, X)> struct Y {};
 Y<operator<=> y; // ill-formed; previously well-formed} â *end example*]

[5](#lex-5)

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

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


**Change:** Type of UTF-8 string and character literals[.](#lex-5.sentence-1)

  


**Rationale:** Required for new features[.](#lex-5.sentence-2)

The changed types enable function overloading, template specialization, and
type deduction to distinguish ordinary and UTF-8 string and character literals[.](#lex-5.sentence-3)

  


**Effect on original feature:** Valid C++ 2017 code that depends on
UTF-8 string literals having type âarray of const charâ and
UTF-8 character literals having type âcharâ
is not valid in this revision of C++[.](#lex-5.sentence-4)

[*Example [4](#lex-example-4)*: const auto *u8s = u8"text"; // u8s previously deduced as const char*; now deduced as const char8_t*const char *ps = u8s; // ill-formed; previously well-formedauto u8c = u8'c'; // u8c previously deduced as char; now deduced as char8_tchar *pc = &u8c; // ill-formed; previously well-formed std::string s = u8"text"; // ill-formed; previously well-formedvoid f(const char *s);
f(u8"text"); // ill-formed; previously well-formedtemplate<typename> struct ct;template<> struct ct<char> {using type = char;};
ct<decltype(u8'c')>::type x; // ill-formed; previously well-formed. â *end example*]

### [C.3.3](#basic) [[basic]](basic "6 Basics"): basics [[diff.cpp17.basic]](diff.cpp17.basic)

[1](#basic-1)

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

**Affected subclause:** [[basic.life]](basic.life)  


**Change:** A pseudo-destructor call ends the lifetime of
the object to which it is applied[.](#basic-1.sentence-1)

  


**Rationale:** Increase consistency of the language model[.](#basic-1.sentence-2)

  


**Effect on original feature:** Valid ISO C++ 2017 code may be ill-formed or
have undefined behavior in this revision of C++[.](#basic-1.sentence-3)

[*Example [1](#basic-example-1)*: int f() {int a = 123; using T = int;
 a.~T(); return a; // undefined behavior; previously returned 123} â *end example*]

[2](#basic-2)

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

**Affected subclause:** [[intro.races]](intro.races)  


**Change:** Except for the initial release operation,
a release sequence consists solely of atomic read-modify-write operations[.](#basic-2.sentence-1)

  


**Rationale:** Removal of rarely used and confusing feature[.](#basic-2.sentence-2)

  


**Effect on original feature:** If a memory_order_release atomic store is followed
by a memory_order_relaxed store to the same variable by the same thread,
then reading the latter value with a memory_order_acquire load
no longer provides any âhappens beforeâ guarantees,
even in the absence of intervening stores by another thread[.](#basic-2.sentence-3)

### [C.3.4](#expr) [[expr]](expr "7 Expressions"): expressions [[diff.cpp17.expr]](diff.cpp17.expr)

[1](#expr-1)

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

**Affected subclause:** [[expr.prim.lambda.capture]](expr.prim.lambda.capture)  


**Change:** Implicit lambda capture may capture additional entities[.](#expr-1.sentence-1)

  


**Rationale:** Rule simplification, necessary to resolve interactions with constexpr if[.](#expr-1.sentence-2)

  


**Effect on original feature:** Lambdas with a [*capture-default*](expr.prim.lambda.capture#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") may capture local entities
that were not captured in C++ 2017
if those entities are only referenced in contexts
that do not result in an odr-use[.](#expr-1.sentence-3)

### [C.3.5](#dcl.dcl) [[dcl]](dcl "9 Declarations"): declarations [[diff.cpp17.dcl.dcl]](diff.cpp17.dcl.dcl)

[1](#dcl.dcl-1)

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

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


**Change:** Unnamed classes with a typedef name for linkage purposes
can contain only C-compatible constructs[.](#dcl.dcl-1.sentence-1)

  


**Rationale:** Necessary for implementability[.](#dcl.dcl-1.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code may be ill-formed in this revision of C++[.](#dcl.dcl-1.sentence-3)

[*Example [1](#dcl.dcl-example-1)*: typedef struct {void f() {} // ill-formed; previously well-formed} S; â *end example*]

[2](#dcl.dcl-2)

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

**Affected subclause:** [[dcl.fct.default]](dcl.fct.default)  


**Change:** A function cannot have different default arguments
in different translation units[.](#dcl.dcl-2.sentence-1)

  


**Rationale:** Required for modules support[.](#dcl.dcl-2.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code may be ill-formed in this revision of C++,
with no diagnostic required[.](#dcl.dcl-2.sentence-3)

[*Example [2](#dcl.dcl-example-2)*: // Translation unit 1int f(int a = 42);int g() { return f(); }// Translation unit 2int f(int a = 76) { return a; } // ill-formed, no diagnostic required; previously well-formedint g();int main() { return g(); } // used to return 42 â *end example*]

[3](#dcl.dcl-3)

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

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


**Change:** A class that has user-declared constructors is never an aggregate[.](#dcl.dcl-3.sentence-1)

  


**Rationale:** Remove potentially error-prone aggregate initialization
which may apply notwithstanding the declared constructors of a class[.](#dcl.dcl-3.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code that aggregate-initializes
a type with a user-declared constructor
may be ill-formed or have different semantics
in this revision of C++[.](#dcl.dcl-3.sentence-3)

[*Example [3](#dcl.dcl-example-3)*: struct A { // not an aggregate; previously an aggregate A() = delete;};

struct B { // not an aggregate; previously an aggregate B() = default; int i = 0;};

struct C { // not an aggregate; previously an aggregate C(C&&) = default; int a, b;};

A a{}; // ill-formed; previously well-formed B b = {1}; // ill-formed; previously well-formedauto* c = new C{2, 3}; // ill-formed; previously well-formedstruct Y;

struct X {operator Y();};

struct Y { // not an aggregate; previously an aggregate Y(const Y&) = default;
 X x;};

Y y{X{}}; // copy constructor call; previously aggregate-initialization â *end example*]

[4](#dcl.dcl-4)

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

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


**Change:** Boolean conversion from a pointer or pointer-to-member type
is now a narrowing conversion[.](#dcl.dcl-4.sentence-1)

  


**Rationale:** Catches bugs[.](#dcl.dcl-4.sentence-2)

  


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

[*Example [4](#dcl.dcl-example-4)*: bool y[] = { "bc" }; // ill-formed; previously well-formed â *end example*]

### [C.3.6](#class) [[class]](class "11 Classes"): classes [[diff.cpp17.class]](diff.cpp17.class)

[1](#class-1)

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

**Affected subclauses:** [[class.ctor]](class.ctor) and [[class.conv.fct]](class.conv.fct)  


**Change:** The class name can no longer be used parenthesized
immediately after an explicit [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") in a constructor declaration[.](#class-1.sentence-1)

The [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") can no longer be used parenthesized
immediately after an explicit [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") in a conversion function declaration[.](#class-1.sentence-2)

  


**Rationale:** Necessary for new functionality[.](#class-1.sentence-3)

  


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

[*Example [1](#class-example-1)*: struct S {explicit (S)(const S&); // ill-formed; previously well-formedexplicit (operator int)(); // ill-formed; previously well-formedexplicit(true) (S)(int); // OK}; â *end example*]

[2](#class-2)

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

**Affected subclauses:** [[class.ctor]](class.ctor) and [[class.dtor]](class.dtor)  


**Change:** A [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") is no longer valid as the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") of a constructor or destructor[.](#class-2.sentence-1)

  


**Rationale:** Remove potentially error-prone option for redundancy[.](#class-2.sentence-2)

  


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

[*Example [2](#class-example-2)*: template<class T>struct A { A<T>(); // error: [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") not allowed for constructor A(int); // OK, injected-class-name used~A<T>(); // error: [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") not allowed for destructor}; â *end example*]

[3](#class-3)

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

**Affected subclause:** [[class.copy.elision]](class.copy.elision)  


**Change:** A function returning an implicitly movable entity
may invoke a constructor taking an rvalue reference to a type
different from that of the returned expression[.](#class-3.sentence-1)

Function and catch-clause parameters can be thrown using move constructors[.](#class-3.sentence-2)

  


**Rationale:** Side effect of making it easier to write
more efficient code that takes advantage of moves[.](#class-3.sentence-3)

  


**Effect on original feature:** Valid C++ 2017 code may fail to compile or have different semantics
in this revision of C++[.](#class-3.sentence-4)

[*Example [3](#class-example-3)*: struct base { base();
 base(base const &);private: base(base &&);};

struct derived : base {};

base f(base b) {throw b; // error: base(base &&) is private derived d; return d; // error: base(base &&) is private}struct S { S(const char *s) : m(s) { } S(const S&) = default;
 S(S&& other) : m(other.m) { other.m = nullptr; }const char * m;};

S consume(S&& s) { return s; }void g() { S s("text");
 consume(static_cast<S&&>(s)); char c = *s.m; // undefined behavior; previously ok} â *end example*]

### [C.3.7](#over) [[over]](over "12 Overloading"): overloading [[diff.cpp17.over]](diff.cpp17.over)

[1](#over-1)

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

**Affected subclause:** [[over.match.oper]](over.match.oper)  


**Change:** Equality and inequality expressions can now find
reversed and rewritten candidates[.](#over-1.sentence-1)

  


**Rationale:** Improve consistency of equality with three-way comparison
and make it easier to write the full complement of equality operations[.](#over-1.sentence-2)

  


**Effect on original feature:** For certain pairs of types where one is convertible to the other,
equality or inequality expressions between an object of one type
and an object of the other type invoke a different operator[.](#over-1.sentence-3)

Also, for certain types, equality or inequality expressions
between two objects of that type become ambiguous[.](#over-1.sentence-4)

[*Example [1](#over-example-1)*: struct A {operator int() const;};

bool operator==(A, int); // #1// #2 is built-in candidate: bool operator==(int, int);// #3 is built-in candidate: bool operator!=(int, int);int check(A x, A y) {return (x == y) + // ill-formed; previously well-formed(10 == x) + // calls #1, previously selected #2(10 != x); // calls #1, previously selected #3} â *end example*]

[2](#over-2)

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

**Affected subclause:** [[over.match.oper]](over.match.oper)  


**Change:** Overload resolution may change for equality operators ([[expr.eq]](expr.eq "7.6.10 Equality operators"))[.](#over-2.sentence-1)

  


**Rationale:** Support calling operator== with reversed order of arguments[.](#over-2.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code that uses equality operators with conversion functions
may be ill-formed or have different semantics in this revision of C++[.](#over-2.sentence-3)

[*Example [2](#over-example-2)*: struct A {operator int() const { return 10; }};

bool operator==(A, int); // #1// #2 is built-in candidate: bool operator==(int, int);bool b = 10 == A(); // calls #1 with reversed order of arguments; previously selected #2struct B {bool operator==(const B&); // member function with no cv-qualifier};
B b1;bool eq = (b1 == b1); // ambiguous; previously well-formed â *end example*]

### [C.3.8](#temp) [[temp]](temp "13 Templates"): templates [[diff.cpp17.temp]](diff.cpp17.temp)

[1](#temp-1)

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

**Affected subclause:** [[temp.names]](temp.names)  


**Change:** An [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") that is followed by a < and for which name lookup
finds nothing or finds a function
will be treated as a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") in order to potentially cause argument-dependent lookup to be performed[.](#temp-1.sentence-1)

  


**Rationale:** It was problematic to call a function template
with an explicit template argument list
via argument-dependent lookup
because of the need to have a template with the same name
visible via normal lookup[.](#temp-1.sentence-2)

  


**Effect on original feature:** Previously valid code that uses a function name
as the left operand of a < operator
would become ill-formed[.](#temp-1.sentence-3)

[*Example [1](#temp-example-1)*: struct A {};bool operator<(void (*fp)(), A);void f() {}int main() { A a;
 f < a; // ill-formed; previously well-formed(f) < a; // still well-formed} â *end example*]

### [C.3.9](#except) [[except]](except "14 Exception handling"): exception handling [[diff.cpp17.except]](diff.cpp17.except)

[1](#except-1)

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

**Affected subclause:** [[except.spec]](except.spec)  


**Change:** Remove throw() exception specification[.](#except-1.sentence-1)

  


**Rationale:** Removal of obsolete feature that has been replaced by noexcept[.](#except-1.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 function declaration, member function declaration, function
pointer declaration, or function reference declaration that uses throw() for its exception specification will be rejected as ill-formed in this
revision of C++[.](#except-1.sentence-3)

It should simply be replaced with noexcept for no
change of meaning since C++ 2017[.](#except-1.sentence-4)

[*Note [1](#except-note-1)*:

There is no way to write a function declaration
that is non-throwing in this revision of C++
and is also non-throwing in C++ 2003
except by using the preprocessor to generate
a different token sequence in each case[.](#except-1.sentence-5)

â *end note*]

### [C.3.10](#library) [[library]](library "16 Library introduction"): library introduction [[diff.cpp17.library]](diff.cpp17.library)

[1](#library-1)

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

**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:[<barrier>](barrier.syn#header:%3cbarrier%3e "32.9.3.2 Header <barrier> synopsis [barrier.syn]"),[<bit>](bit.general#header:%3cbit%3e "22.11.1 General [bit.general]"),[<charconv>](charconv.syn#header:%3ccharconv%3e "28.2.1 Header <charconv> synopsis [charconv.syn]"),[<compare>](compare.syn#header:%3ccompare%3e "17.12.1 Header <compare> synopsis [compare.syn]"),[<concepts>](concepts.syn#header:%3cconcepts%3e "18.3 Header <concepts> synopsis [concepts.syn]"),[<coroutine>](coroutine.syn#header:%3ccoroutine%3e "17.13.2 Header <coroutine> synopsis [coroutine.syn]"),[<format>](format.formatter.spec#header:%3cformat%3e "28.5.6.4 Formatter specializations [format.formatter.spec]"),[<latch>](latch.syn#header:%3clatch%3e "32.9.2.2 Header <latch> synopsis [latch.syn]"),[<numbers>](numbers.syn#header:%3cnumbers%3e "29.8.1 Header <numbers> synopsis [numbers.syn]"),[<ranges>](ranges.syn#header:%3cranges%3e "25.2 Header <ranges> synopsis [ranges.syn]"),[<semaphore>](semaphore.syn#header:%3csemaphore%3e "32.8.2 Header <semaphore> synopsis [semaphore.syn]"),[<source_location>](source.location.syn#header:%3csource_location%3e "17.8.1 Header <source_­location> synopsis [source.location.syn]"),[<span>](span.syn#header:%3cspan%3e "23.7.2.1 Header <span> synopsis [span.syn]"),[<stop_token>](thread.stoptoken.syn#header:%3cstop_token%3e "32.3.2 Header <stop_­token> synopsis [thread.stoptoken.syn]"),[<syncstream>](syncstream.syn#header:%3csyncstream%3e "31.11.1 Header <syncstream> synopsis [syncstream.syn]"), and[<version>](version.syn#header:%3cversion%3e "17.3.2 Header <version> synopsis [version.syn]")[.](#library-1.sentence-3)

Valid C++ 2017 code that #includes headers with these names may be
invalid in this revision of C++[.](#library-1.sentence-4)

[2](#library-2)

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

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


**Change:** Remove vacuous C++ header files[.](#library-2.sentence-1)

  


**Rationale:** The empty headers implied a false requirement to achieve C compatibility with the C++ headers[.](#library-2.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that #includes any of the following headers may fail to compile:<ccomplex>,<ciso646>,<cstdalign>,<cstdbool>, and<ctgmath>[.](#library-2.sentence-3)

To retain the same behavior:

- [(2.1)](#library-2.1)

a #include of <ccomplex> can be replaced by
a #include of [<complex>](complex.syn#header:%3ccomplex%3e "29.4.2 Header <complex> synopsis [complex.syn]"),

- [(2.2)](#library-2.2)

a #include of <ctgmath> can be replaced by
a #include of [<cmath>](cmath.syn#header:%3ccmath%3e "29.7.1 Header <cmath> synopsis [cmath.syn]") and
a #include of [<complex>](complex.syn#header:%3ccomplex%3e "29.4.2 Header <complex> synopsis [complex.syn]"),
and

- [(2.3)](#library-2.3)

a #include of<ciso646>,<cstdalign>, or<cstdbool> can simply be removed[.](#library-2.sentence-4)

### [C.3.11](#containers) [[containers]](containers "23 Containers library"): containers library [[diff.cpp17.containers]](diff.cpp17.containers)

[1](#containers-1)

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

**Affected subclauses:** [[forward.list]](forward.list) and [[list]](list)  


**Change:** Return types of remove, remove_if, and unique changed from void to container​::​size_type[.](#containers-1.sentence-1)

  


**Rationale:** Improve efficiency and convenience of finding number of removed elements[.](#containers-1.sentence-2)

  


**Effect on original feature:** Code that depends on the return types might have different semantics in this revision of C++[.](#containers-1.sentence-3)

Translation units compiled against this version of C++ may be incompatible with
translation units compiled against C++ 2017, either failing to link or having undefined behavior[.](#containers-1.sentence-4)

### [C.3.12](#iterators) [[iterators]](iterators "24 Iterators library"): iterators library [[diff.cpp17.iterators]](diff.cpp17.iterators)

[1](#iterators-1)

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

**Affected subclause:** [[iterator.traits]](iterator.traits)  


**Change:** The specialization of iterator_traits for void* and
for function pointer types no longer contains any nested typedefs[.](#iterators-1.sentence-1)

  


**Rationale:** Corrects an issue misidentifying pointer types that are not incrementable
as iterator types[.](#iterators-1.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that relies on the presence of the typedefs
may fail to compile, or have different behavior[.](#iterators-1.sentence-3)

### [C.3.13](#alg.reqs) [[algorithms]](algorithms "26 Algorithms library"): algorithms library [[diff.cpp17.alg.reqs]](diff.cpp17.alg.reqs)

[1](#alg.reqs-1)

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

**Affected subclause:** [[algorithms.requirements]](algorithms.requirements)  


**Change:** The number and order of deducible template parameters for algorithm declarations
is now unspecified, instead of being as-declared[.](#alg.reqs-1.sentence-1)

  


**Rationale:** Increase implementor freedom and allow some function templates
to be implemented as function objects with templated call operators[.](#alg.reqs-1.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that passes explicit template arguments to
algorithms not explicitly specified to allow such in this version of C++
may fail to compile or have undefined behavior[.](#alg.reqs-1.sentence-3)

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

[1](#input.output-1)

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

**Affected subclause:** [[istream.extractors]](istream.extractors)  


**Change:** Character array extraction only takes array types[.](#input.output-1.sentence-1)

  


**Rationale:** Increase safety via preventing buffer overflow at compile time[.](#input.output-1.sentence-2)

  


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

[*Example [1](#input.output-example-1)*: auto p = new char[100];char q[100];
std::cin >> std::setw(20) >> p; // ill-formed; previously well-formed std::cin >> std::setw(20) >> q; // OK â *end example*]

[2](#input.output-2)

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

**Affected subclause:** [[ostream.inserters.character]](ostream.inserters.character)  


**Change:** Overload resolution for ostream inserters used with UTF-8 literals[.](#input.output-2.sentence-1)

  


**Rationale:** Required for new features[.](#input.output-2.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code that passes UTF-8 literals tobasic_ostream<char, ...>​::​operator<< orbasic_ostream<wchar_t, ...>​::​operator<< is now ill-formed[.](#input.output-2.sentence-3)

[*Example [2](#input.output-example-2)*: std::cout << u8"text"; // previously called operator<<(const char*) and printed a string;// now ill-formed std::cout << u8'X'; // previously called operator<<(char) and printed a character;// now ill-formed â *end example*]

[3](#input.output-3)

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

**Affected subclause:** [[ostream.inserters.character]](ostream.inserters.character)  


**Change:** Overload resolution for ostream inserters
used with wchar_t, char16_t, or char32_t types[.](#input.output-3.sentence-1)

  


**Rationale:** Removal of surprising behavior[.](#input.output-3.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code that passeswchar_t, char16_t, or char32_t characters or strings
to basic_ostream<char, ...>​::​operator<< or
that passes char16_t or char32_t characters or strings
to basic_ostream<wchar_t, ...>​::​operator<< is now ill-formed[.](#input.output-3.sentence-3)

[*Example [3](#input.output-example-3)*: std::cout << u"text"; // previously formatted the string as a pointer value;// now ill-formed std::cout << u'X'; // previously formatted the character as an integer value;// now ill-formed â *end example*]

[4](#input.output-4)

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

**Affected subclause:** [[fs.class.path]](fs.class.path)  


**Change:** Return type of filesystem path format observer member functions[.](#input.output-4.sentence-1)

  


**Rationale:** Required for new features[.](#input.output-4.sentence-2)

  


**Effect on original feature:** Valid C++ 2017 code that depends on the u8string() andgeneric_u8string() member functions of std​::​filesystem​::​path returning std​::​string is not valid in this revision of C++[.](#input.output-4.sentence-3)

[*Example [4](#input.output-example-4)*: std::filesystem::path p;
std::string s1 = p.u8string(); // ill-formed; previously well-formed std::string s2 = p.generic_u8string(); // ill-formed; previously well-formed â *end example*]

### [C.3.15](#depr) [[depr]](depr "Annex D (normative) Compatibility features"): compatibility features [[diff.cpp17.depr]](diff.cpp17.depr)

[1](#depr-1)

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

**Change:** Remove uncaught_exception[.](#depr-1.sentence-1)

  


**Rationale:** The function did not have a clear specification when multiple exceptions were
active, and has been superseded by uncaught_exceptions[.](#depr-1.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that calls std​::​uncaught_exception may fail
to compile[.](#depr-1.sentence-3)

It can be revised to use std​::​uncaught_exceptions instead,
for clear and portable semantics[.](#depr-1.sentence-4)

[2](#depr-2)

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

**Change:** Remove support for adaptable function API[.](#depr-2.sentence-1)  

**Rationale:** The deprecated support relied on a limited convention that could not be
extended to support the general case or new language features[.](#depr-2.sentence-2)

It has been
superseded by direct language support with decltype, and by thestd​::​bind and std​::​not_fn function templates[.](#depr-2.sentence-3)

  


**Effect on original feature:** A valid C++ 2017 program that relies on the presence of result_type,argument_type, first_argument_type, orsecond_argument_type in a standard library class may fail to compile[.](#depr-2.sentence-4)

A
valid C++ 2017 program that calls not1 or not2, or uses the
class templates unary_negate or binary_negate, may fail to
compile[.](#depr-2.sentence-5)

[3](#depr-3)

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

**Change:** Remove redundant members from std​::​allocator[.](#depr-3.sentence-1)

  


**Rationale:** std​::​allocator was overspecified, encouraging direct usage in user containers
rather than relying on std​::​allocator_traits, leading to poor containers[.](#depr-3.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that directly makes use of the pointer,const_pointer, reference, const_reference,rebind, address, construct, destroy, ormax_size members of std​::​allocator, or that directly callsallocate with an additional hint argument, may fail to compile[.](#depr-3.sentence-3)

[4](#depr-4)

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

**Change:** Remove raw_storage_iterator[.](#depr-4.sentence-1)

  


**Rationale:** The iterator encouraged use of potentially-throwing algorithms, but did
not return the number of elements successfully constructed,
as would be necessary to destroy them[.](#depr-4.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that uses this iterator class may fail to compile[.](#depr-4.sentence-3)

[5](#depr-5)

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

**Change:** Remove temporary buffers API[.](#depr-5.sentence-1)  

**Rationale:** The temporary buffer facility was intended to provide an efficient optimization
for small memory requests, but there is little evidence this was achieved in
practice, while requiring the user to provide their own exception-safe wrappers
to guard use of the facility in many cases[.](#depr-5.sentence-2)

  


**Effect on original feature:** A valid C++ 2017 program that calls get_temporary_buffer orreturn_temporary_buffer may fail to compile[.](#depr-5.sentence-3)

[6](#depr-6)

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

**Change:** Remove shared_ptr​::​unique[.](#depr-6.sentence-1)

  


**Rationale:** The result of a call to this member function is not reliable in the presence of
multiple threads and weak pointers[.](#depr-6.sentence-2)

The member function use_count is
similarly unreliable, but has a clearer contract in such cases, and remains
available for well-defined use in single-threaded cases[.](#depr-6.sentence-3)

  


**Effect on original feature:** A valid C++ 2017 program that calls unique on a shared_ptr object may fail to compile[.](#depr-6.sentence-4)

[7](#depr-7)

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

**Affected subclause:** [[depr.meta.types]](depr.meta.types)  


**Change:** Remove deprecated type traits[.](#depr-7.sentence-1)

  


**Rationale:** The traits had unreliable or awkward interfaces[.](#depr-7.sentence-2)

The is_literal_type trait provided no way to detect which subset of constructors and member
functions of a type were declared constexpr[.](#depr-7.sentence-3)

The result_of trait had a surprising syntax that did not directly support function types[.](#depr-7.sentence-4)

It has been superseded by the invoke_result trait[.](#depr-7.sentence-5)

  


**Effect on original feature:** A valid C++ 2017 program that relies on the is_literal_type orresult_of type traits, on the is_literal_type_v variable template,
or on the result_of_t alias template may fail to compile[.](#depr-7.sentence-6)
