Ответ 1
Примечание. В этом сообщении я считаю, что "изменение прерывания" должно быть либо, либо и тем, и другого:
1. изменение, которое сделает законным С++ 11 плохо сформированным при компиляции С++ 14 и;
2. изменение, которое изменит поведение во время выполнения при компиляции С++ 14, vs С++ 11.
С++ 11 vs С++ 14, что говорит стандарт?
Стандартная черновик (n3797) имеет раздел, посвященный только такой информации, где он описывает (потенциально нарушающие) различия между одной версией стандарта и другой.
Это сообщение использовало этот раздел [diff.cpp11]
в качестве основы для полуразработанного обсуждения изменений, которые могут повлиять на код, написанный для С++ 11, но скомпилированный как С++ 14.
C.3.1] Цифровые разделители
Разделитель цифр был введен таким образом, чтобы можно было более читаемым образом писать числовые литералы и разделить их таким образом, что это более естественный способ.
int x = 10000000; // (1)
int y = 10'000'000; // (2), C++14
Легко видеть, что (2) намного легче читать, чем (1) в приведенном выше фрагменте, в то время как оба инициализатора имеют одинаковое значение.
Потенциальная проблема в этой функции заключается в том, что одинарная кавычка всегда обозначала начало/конец символьного литерала в С++ 11, но в С++ 14 одиночная кавычка может либо окружать буквенный символ, или используется ранее показанным образом (2).
Пример фрагмента, легальный как на С++ 11, так и на С++ 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] Размер освобождения
С++ 14 предоставляет возможность объявить глобальную перегрузку operator delete
, подходящую для размера освобождения, что было невозможно в С++ 11.
Однако стандарт также предусматривает, что разработчик не может объявить только одну из двух связанных функций ниже, он должен объявить либо none, либо как; который указан в [new.delete.single] p11.
void operator delete (void*) noexcept;
void operator delete (void*, std::size_t) noexcept; // sized deallocation
Дополнительная информация о потенциальной проблеме:
Существующие программы, которые переопределяют глобальную версию без модификации, также не определите размер версии. Когда реализация вводит размер версии, замена будет неполной, и вполне вероятно, что программы будут ссылаться на освобождающего объекты, выделенные программируемым распределителем.
Примечание: Цитата взята из n3536 - Расширенное освобождение С++
(Примечание. Больше интереса имеется в документе под названием n3536 - С++ Sized Deallocation, написанном Лоуренсом Кроулом)
C.3.3] constexpr
функции-члены, уже неявно const
Есть много изменений в constexpr в С++ 14, но единственное изменение, которое изменит семантику между С++ 11 и С++ 14, - это постоянство функции-члена, помеченной как constexpr.
Обоснование этого изменения заключается в том, чтобы позволить членам-членам constexpr мутировать объект, к которому они принадлежат, что-то, что разрешено из-за релаксации constexpr.
struct A { constexpr int func (); };
// struct A { constexpr int func () const; }; <-- C++11
// struct A { constexpr int func (); }; <-- C++14
Рекомендуемый материал об этом изменении, и почему это достаточно важно, чтобы ввести потенциальный поломка кода:
- Блог Andrzej С++ - функция "constexpr" не является "const"
- open-std.org - функции-члены constexpr и неявный const
- ( open-std.org - Расслабляющие ограничения на функции constexpr)
Пример фрагмента, законный как в С++ 11, так и в С++ 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
был удален из стандарта Библиотека, потому что считается опасной.
Последствия этого - это, конечно, попытка скомпилировать код, написанный для С++ 11, в С++ 14, где такая функция используется, скорее всего, просто не скомпилируется.
(Примечание: существуют способы записи code, которые не поддаются компиляции и имеют другое поведение, которое зависит от удаление std::gets
из стандартной библиотеки)