What breaking changes are introduced in C++11?

后端 未结 9 1654
陌清茗
陌清茗 2020-11-22 14:34

I know that at least one of the changes in C++11 that will cause some old code to stop compiling: the introduction of explicit operator bool() in the standard l

相关标签:
9条回答
  • 2020-11-22 15:34

    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, or noreturn as macros is invalid in C++0x.

    0 讨论(0)
  • 2020-11-22 15:36

    There's been a lot of discussion of implicit move breaking backward compatibility

    (an older page with relevant discussion)

    If you read down into the comments, implicit move return is also a breaking change.

    0 讨论(0)
  • 2020-11-22 15:38

    Breaking change?

    Well, for one thing, if you used decltype, constexpr, nullptr, etc. as identifiers then you may be in trouble...

    0 讨论(0)
提交回复
热议问题