Annex C (informative) Compatibility [diff]

C.1 C++ and ISO C++ 2017 [diff.cpp17]

C.1.5 [dcl.dcl]: declarations [diff.cpp17.dcl.dcl]

Affected subclause: [dcl.typedef]
Change: Unnamed classes with a typedef name for linkage purposes can contain only C-compatible constructs.

Rationale: Necessary for implementability.

Effect on original feature: Valid C++ 2017 code may be ill-formed in this revision of C++.
typedef struct { void f() {} // ill-formed; previously well-formed } S;
Affected subclause: [dcl.fct.default]
Change: A function cannot have different default arguments in different translation units.

Rationale: Required for modules support.

Effect on original feature: Valid C++ 2017 code may be ill-formed in this revision of C++, with no diagnostic required.
// Translation unit 1 int f(int a = 42); int g() { return f(); } // Translation unit 2 int f(int a = 76) { return a; } // ill-formed, no diagnostic required; previously well-formed int g(); int main() { return g(); } // used to return 42
Affected subclause: [dcl.init.aggr]
Change: A class that has user-declared constructors is never an aggregate.

Rationale: Remove potentially error-prone aggregate initialization which may apply notwithstanding the declared constructors of a class.

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++.
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-formed auto* c = new C{2, 3}; // ill-formed; previously well-formed struct 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
Affected subclause: [dcl.init.list]
Change: Boolean conversion from a pointer or pointer-to-member type is now a narrowing conversion.

Rationale: Catches bugs.

Effect on original feature: Valid C++ 2017 code may fail to compile in this revision of C++.
For example: bool y[] = { "bc" }; // ill-formed; previously well-formed