What breaking changes are introduced in C++11?
Solution 1:
The FDIS has a section for incompatibilities, at appendix C.2
"C++ and ISO C++ 2003".
Summary, paraphrasing the FDIS here, to make it (better) suitable as a SO answer. I added some examples of my own to illustrate the differences.
There are a few library-related incompatibilities where I don't exactly know the implications of, so I leave those for others to elaborate on.
Core language
#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"
#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .
New keywords: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, and thread_local
Certain integer literals larger than can be represented by long could change from an unsigned integer type to signed long long.
Valid C++ 2003 code that uses integer division rounds the result toward 0 or toward negative infinity, whereas C++0x always rounds the result toward 0.
(admittedly not really a compatibility problem for most people).
Valid C++ 2003 code that uses the keyword
auto
as a storage class specifier may be invalid in C++0x.
Narrowing conversions cause incompatibilities with C++03. For example, the following code is valid in C++ 2003 but invalid in this International Standard because double to int is a narrowing conversion:
int x[] = { 2.0 };
Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed.
A valid C++ 2003 program that uses one of these special member functions in a context where the definition is not required (e.g., in an expresion that is not potentially evaluated) becomes ill-formed.
Example by me:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Such sizeof tricks have been used by some SFINAE, and needs to be changed now :)
User-declared destructors have an implicit exception specification.
Example by me:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
This code calls terminate
in C++0x, but does not in C++03. Because the implicit exception specification of A::~A
in C++0x is noexcept(true)
.
A valid C++ 2003 declaration containing
export
is ill-formed in C++0x.
A valid C++ 2003 expression containing
>
followed immediately by another>
may now be treated as closing two templates.
In C++03, >>
would always be the shift-operator token.
Allow dependent calls of functions with internal linkage.
Example by me:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
In C++03, this calls f(long)
, but in C++0x, this calls f(int)
. It should be noted that in both C++03 and C++0x, the following calls f(B)
(the instantiation context still only considers extern linkage declarations).
struct B { };
struct A : B { };
template<typename T>
void g(T t) { f(t); }
static void f(A) { }
void f(B) { }
int main() { A a; g(a); }
The better matching f(A)
is not taken, because it does not have external linkage.
Library changes
Valid C++ 2003 code that uses any identifiers added to the C++ standard library of C++0x may fail to compile or produce different results in This International Standard.
Valid C++ 2003 code that
#includes
headers with names of new C++0x standard library headers may be invalid in this International Standard.
Valid C++ 2003 code that has been compiled expecting swap to be in
<algorithm>
may have to instead include<utility>
The global namespace
posix
is now reserved for standardization.
Valid C++ 2003 code that defines
override
,final
,carries_dependency
, ornoreturn
as macros is invalid in C++0x.
Solution 2:
The meaning of the auto keyword changed.
Solution 3:
Breaking change?
Well, for one thing, if you used decltype
, constexpr
, nullptr
, etc. as identifiers then you may be in trouble...