Примечание. В этом посте я считаю, что "критическое изменение" относится к одному из двух или к обоим;
1. a change that will make legal C++11 ill-formed when compiled as C++14, and;
2 . изменение, которое изменит поведение во время выполнения при компиляции C++14 по сравнению с C++11.
C++11 и C++14, что говорит стандарт?
Стандартный проект (n3797) раздел, предназначенный именно для такого рода информации, где описываются (потенциально критические) различия между одной версией стандарта и другой.
В этом посте этот раздел [diff.cpp11]
использовался как основа для полуобстоятельного обсуждения изменений, которые могут повлиять на код, написанный для C++11, но скомпилированный как C++14< /эм>.
C.3.1] Разделители цифр
Разделитель цифр был введен, чтобы можно было более удобочитаемым образом записывать числовые литералы и разделять их более естественным образом.
int x = 10000000; // (1)
int y = 10'000'000; // (2), C++14
Нетрудно заметить, что (2) намного легче читать, чем (1) в приведенном выше фрагменте, хотя оба инициализатора имеют одинаковое значение.
Потенциальная проблема, связанная с этой функцией, заключается в том, что одинарная кавычка всегда обозначала начало/конец символьного литерала в C++11, но в C++14 одинарная кавычка может либо окружать символьный литерал, либо использоваться ранее показанным способом (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.delete.single]p11.
void operator delete (void*) noexcept;
void operator delete (void*, std::size_t) noexcept; // sized deallocation
Дополнительная информация о потенциальной проблеме:
Существующие программы, которые переопределяют глобальную версию без размера, также не определяют версию с размером. Когда реализация вводит размерную версию, замена будет неполной, и вполне вероятно, что программы будут вызывать предоставленный реализацией размерный освободитель для объектов, выделенных с помощью предоставленного программистом распределителя.
Примечание. Цитата взята с сайта n3536 — отключение размера C++
(Примечание: больше интересного можно найти в статье под названием n3536 - Освобождение размера C++, написанное Лоуренсом Кроулом )
C.3.3] constexpr
функции-члены, больше не неявно const
В constexpr в C++14 внесено много изменений, но единственное изменение, которое изменит семантику между C++11 и C++14 em> — это постоянство функции-члена, помеченной как constexpr.
Смысл этого изменения в том, чтобы позволить constexpr функциям-членам изменять объект, которому они принадлежат, что разрешено из-за ослабление constexpr.
struct A { constexpr int func (); };
// struct A { constexpr int func () const; }; <-- C++11
// struct A { constexpr int func (); }; <-- C++14
Рекомендуемый материал об этом изменении и почему это достаточно важно, чтобы представить потенциальный взлом кода:
Пример фрагмента кода, допустимый как в 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
из Стандартной библиотеки )
person
Filip Roséen - refp
schedule
01.06.2014