FDIS zawiera sekcję dotyczącą niezgodności w dodatku C.2
„C ++ i ISO C ++ 2003”.
Podsumowanie, parafrazując tutaj FDIS, aby uczynić go (lepszym) odpowiednim jako odpowiedź SO. Dodałem kilka własnych przykładów, aby zilustrować różnice.
Istnieje kilka niezgodności związanych z biblioteką, w których nie znam dokładnie konsekwencji, więc pozostawiam je innym do rozwinięcia.
Podstawowy język
#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 .
Nowe słowa kluczowe: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert i thread_local
Niektóre literały całkowite większe niż mogą być reprezentowane przez długie, mogą zmienić się z typu całkowitego bez znaku na znak długi.
Prawidłowy kod C ++ 2003, który używa dzielenia liczb całkowitych, zaokrągla wynik w kierunku 0 lub w kierunku ujemnej nieskończoności, podczas gdy C ++ 0x zawsze zaokrągla wynik w kierunku 0.
(co prawda nie jest tak naprawdę problemem kompatybilności dla większości ludzi).
Prawidłowy kod C ++ 2003, który używa słowa kluczowego auto
jako specyfikatora klasy pamięci, może być niepoprawny w C ++ 0x.
Zwężenie konwersji powoduje niezgodność z C ++ 03. Na przykład poniższy kod jest poprawny w C ++ 2003, ale jest niepoprawny w tym standardzie międzynarodowym, ponieważ podwójna int to konwersja zawężająca:
int x[] = { 2.0 };
Specjalnie zadeklarowane funkcje specjalne są definiowane jako usunięte, gdy niejawna definicja byłaby źle sformułowana.
Prawidłowy program C ++ 2003, który używa jednej z tych specjalnych funkcji składowych w kontekście, w którym definicja nie jest wymagana (np. W wyrażeniu, które nie jest potencjalnie oceniane) staje się źle sformułowany.
Przykład mojego autorstwa:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Taki rozmiar sztuczek był używany przez niektóre SFINAE i należy go teraz zmienić :)
Destruktory zadeklarowane przez użytkownika mają domyślną specyfikację wyjątku.
Przykład mojego autorstwa:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
Ten kod wywołuje terminate
w C ++ 0x, ale nie w C ++ 03. Ponieważ niejawna specyfikacja wyjątku A::~A
w C ++ 0x to noexcept(true)
.
Prawidłowa deklaracja C ++ 2003 export
jest źle sformułowana w C ++ 0x.
Prawidłowe wyrażenie C ++ 2003 zawierające >
bezpośrednio po nim kolejne >
może być teraz traktowane jako zamknięcie dwóch szablonów.
W C ++ 03 >>
zawsze będzie tokenem shift-operator.
Zezwalaj na zależne wywołania funkcji z wewnętrznym powiązaniem.
Przykład mojego autorstwa:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
W C ++ 03 to wywołuje f(long)
, ale w C ++ 0x to wywołuje f(int)
. Należy zauważyć, że zarówno w C ++ 03, jak i C ++ 0x następujące wywołania f(B)
(kontekst tworzenia instancji nadal uwzględnia tylko deklaracje powiązań zewnętrznych).
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); }
Lepsze dopasowanie f(A)
nie jest podejmowane, ponieważ nie ma powiązania zewnętrznego.
Zmiany w bibliotece
Prawidłowy kod C ++ 2003, który używa dowolnych identyfikatorów dodanych do standardowej biblioteki C ++ C ++ 0x, może nie zostać skompilowany lub wygenerować inne wyniki w niniejszym standardzie międzynarodowym.
Poprawny kod C ++ 2003, który #includes
nagłówki z nazwami nowych nagłówków biblioteki standardowej C ++ 0x mogą być niepoprawne w tym standardzie międzynarodowym.
<algorithm>
Zamiast tego może zostać dołączony prawidłowy kod C ++ 2003, który został skompilowany z oczekiwaniem na zamianę<utility>
Globalna przestrzeń nazw posix
jest teraz zarezerwowana do standaryzacji.
Poprawny kod C ++ 2003, który definiuje override
, final
, carries_dependency
, lub noreturn
jako makra jest nieprawidłowy w C ++ 0x.
export
słowa kluczowego? Zdobędę płaszcz.