Какие изменения, внесенные в C++14, потенциально могут сломать программу, написанную на C++11?
введение
с C++14 (ака. C++1y) стандарт в состоянии, близком к окончательному, программисты должны спросить себя о обратной совместимости и проблемах, связанных с такими.
вопрос
в ответах на этот вопрос говорится, что стандарт имеет приложение посвящен информации об изменениях между переделки.
было бы полезно, если бы эти потенциальные проблемы в ранее упомянутых приложение можно было бы объяснить, возможно, с помощью каких-либо официальных документов, связанных с тем, что там упоминается.
- согласно стандарту: какие изменения внесены в C++14 потенциально может нарушить программу, написанную на C++11?
1 ответ:
Примечание: в этом посте я рассматриваю "breaking change " быть либо тем, либо другим;
1. a change that will make legal C++11 ill-formed when compiled as C++14, and;
2. изменение, которое изменит поведение среды выполнения при компиляции как C++14, vs C++11.
C++11 vs C++14, что говорит стандарт?
стандартный проект ( n3797) имеет a раздел, посвященный именно этому виду информации, где описываются (потенциально нарушающие) различия между одной редакцией стандарта и другой.
этот пост использовал этот раздел,
[diff.cpp11]
, в качестве основы для полу-детального обсуждения изменений, которые могут повлиять на код, написанный для C++11, но собран как C++14.
C. 3. 1] Разделители Цифр
был введен разделитель цифр чтобы можно было более читаемым образом писать числовые литералы и разделять их более естественным образом.
int x = 10000000; // (1) int y = 10'000'000; // (2), C++14
это легко увидеть (2) гораздо легче читать, чем (1) в приведенном выше фрагменте кода, в то время как оба инициализатора имеют одинаковое значение.
потенциальная проблема в отношении этой функции заключается в том, что одиночная кавычка всегда обозначает начало / конец a символ-литерал на C++11, но в C++14 a одиночная кавычка может быть, окружающие символ-литерал, или используется в ранее показанном виде (2).
пример фрагмента, законный в обоих C++11 и C++14, но с разным поведением.
#define M(x, ...) __VA_ARGS__ int a[] = { M(1'2, 3'4, 5) }; // int a[] = { 5 }; <-- C++11 // int a[] = { 3'4, 5 }; <-- C++14 // ^-- semantically equivalent to `{ 34, 5 }`
(Примечание: дополнительная информация о одиночные кавычки как разделители цифр можно найти в n3781.pdf)
C. 3. 2] Размерное Освобождение
C++14 вводит возможность объявить глобальную перегрузку
operator delete
подходит для размера освобождения, что-то, что не было возможно в C++11.однако стандарт также требует, чтобы разработчик не мог объявить только один из двух связанных функции ниже, он должен объявить либо нет или и; что говорится в [new.удалить.single]p11.
void operator delete (void*) noexcept; void operator delete (void*, std::size_t) noexcept; // sized deallocation
дополнительная информация о потенциальной проблеме:
существующие программы, которые переопределяют глобальную версию без размера, также не делают определите размер версии. Когда реализация вводит размер версия, замена была бы неполный и вполне вероятно, что программы вызвали бы реализацию-обеспеченный размерный деаллокатор на объекты, выделенные с помощью программируемого распределителя.
Примечание: цитата взята из n3536 - C++ для размера изъятия
(Примечание: больше интересного можно найти в статье под названием n3536 - C++ для размера изъятия, написано Корячусь Лоуренс )
С. 3.3]
constexpr
функции-члены, больше неявноconst
есть много изменений к constexpr в C++14, но единственное изменение, которое изменит семантику между C++11 и C++14 - это constantness на член-функцию обозначено как constexpr.
обоснование этого изменения заключается в том, чтобы позволить constexpr член-функции мутировать объект, к которому они принадлежат, то, что разрешено из-за релаксация constexpr.
struct A { constexpr int func (); }; // struct A { constexpr int func () const; }; <-- C++11 // struct A { constexpr int func (); }; <-- C++14
рекомендуемый материал по этому изменению, и почему это достаточно важно, чтобы ввести потенциальный код поломки:
- блог Анджея на C++ - функция "constexpr" не является "константные"
- open-std.org - функции-члены constexpr и неявный const
- (open-std.org - расслабляющие ограничения на функции constexpr)
пример фрагмента, законный в обоих C++11 и C++14, но с разными поведение
struct Obj { constexpr int func (int) { return 1; } constexpr int func (float) const { return 2; } };
Obj const a = {}; int const x = a.func (123); // int const x = 1; <-- C++11 // int const x = 2; <-- C++14
C. 3. 4] Удаление
std::gets
std::gets
была удалены из стандартной библиотеки, потому что это считается опасным.последствия этого, конечно, что попытка скомпилировать код, написанный для C++11, в C++14, где используется такая функция, скорее всего, просто не удастся компилировать.
(Примечание: есть способы написания код что не удается скомпилировать, и имеют различное поведение, которое зависит от удаления
std::gets
С Стандартная Библиотека)