В FDIS есть раздел о несовместимостях, в приложении C.2
«C ++ и ISO C ++ 2003».
Резюме, перефразируя FDIS здесь, чтобы сделать его (лучше) пригодным в качестве SO ответа. Я добавил несколько собственных примеров, чтобы проиллюстрировать различия.
Есть несколько несовместимостей, связанных с библиотекой, в которых я точно не знаю последствий, поэтому я оставляю их другим.
Основной язык
#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
Некоторые целочисленные литералы, большие, чем может быть представлено long, могут измениться с целочисленного типа без знака на long long со знаком.
Действительный код C ++ 2003, который использует целочисленное деление, округляет результат до 0 или до отрицательной бесконечности, тогда как C ++ 0x всегда округляет результат до 0.
(по общему признанию не действительно проблема совместимости для большинства людей).
Допустимый код C ++ 2003, который использует ключевое слово auto
в качестве спецификатора класса хранения, может быть недопустимым в C ++ 0x.
Сужающиеся преобразования вызывают несовместимости с C ++ 03. Например, следующий код действителен в C ++ 2003, но недопустим в этом международном стандарте, поскольку преобразование double в 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 >>
всегда будет токен оператора сдвига.
Разрешить зависимые вызовы функций с внутренней связью.
Пример от меня:
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
ключевого слова? Я принесу мне пальто.