У FDIS є розділ щодо несумісності у додатку C.2
"C ++ та ISO C ++ 2003".
Короткий підсумок, перефразовуючи FDIS тут, щоб зробити його (кращим) придатним як відповідь ТА. Я додав кілька власних прикладів, щоб проілюструвати відмінності.
Є кілька несумісностей, пов’язаних з бібліотекою, де я точно не знаю наслідків, тому я залишаю їх іншим детальніше.
Основна мова
#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 .
Нові ключові слова: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert та thread_local
Деякі цілі літерали, більші, ніж можуть бути представлені довгими, можуть змінюватися від непідписаного цілого числа до довгого підписаного.
Дійсний код C ++ 2003, який використовує ціле ділення, округляє результат до 0 або до негативної нескінченності, тоді як C ++ 0x завжди округляє результат до 0.
(правда, це не є проблемою сумісності для більшості людей).
Дійсний код C ++ 2003, який використовує ключове слово auto
як специфікатор класу зберігання, може бути недійсним у C ++ 0x.
Звуження конверсій спричиняє несумісність із C ++ 03. Наприклад, наступний код дійсний у C ++ 2003, але недійсний у цьому Міжнародному стандарті, оскільки подвійний до int - це конверсія звуження:
int x[] = { 2.0 };
Неявно оголошені функції спеціальних членів визначаються як видалені, коли неявне визначення було б неправильно сформовано.
Дійсна програма C ++ 2003, яка використовує одну з цих функцій спеціального члена в контексті, коли визначення не потрібно (наприклад, у виразі, який потенційно не оцінюється) стає неправильним.
Приклад мною:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Такі хитрощі розмірів використовувались у деяких SFINAE, і їх потрібно змінити зараз :)
Задекларовані користувачем деструктори мають неявну специфікацію винятків.
Приклад мною:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
Цей код дзвонить terminate
у C ++ 0x, але не в C ++ 03. Тому що неявна специфікація виключень A::~A
у C ++ 0x є noexcept(true)
.
Дійсна декларація C ++ 2003, що містить export
неправильну форму в C ++ 0x.
Дійсний вираз C ++ 2003, що містить >
негайно інший, >
тепер може трактуватися як закриття двох шаблонів.
У C ++ 03 >>
завжди буде маркер оператора shift.
Дозволити залежні виклики функцій із внутрішнім зв’язком.
Приклад мною:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
У C ++ 03 це дзвінки f(long)
, а у C ++ 0x - це дзвінки f(int)
. Слід зазначити, що і в C ++ 03, і в C ++ 0x є наступні виклики f(B)
(контекст інстанції все ще враховує лише декларації зовнішніх зв'язків).
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); }
Краща відповідність f(A)
не приймається, оскільки вона не має зовнішніх зв'язків.
Зміни бібліотеки
Дійсний код C ++ 2003, який використовує будь-які ідентифікатори, додані до стандартної бібліотеки C ++ C ++ 0x, може не вдатися до компіляції або отримання різних результатів у цьому міжнародному стандарті.
Дійсний код C ++ 2003, що #includes
заголовки з іменами нових стандартних заголовків бібліотек C ++ 0x можуть бути недійсними в цьому Міжнародному стандарті.
Дійсний код C ++ 2003, який був складений, очікуючи на заміну, <algorithm>
може замість цього включити<utility>
Глобальний простір імен posix
тепер зарезервований для стандартизації.
Дійсний C ++ 2003 код , який визначає override
, final
, carries_dependency
або noreturn
як макроси неприпустимий в C ++ 0x.
export
ключового слова? Я дістану мені пальто.