Нарушение const-правильности [размещение нового] ​​и неопределенного поведения - PullRequest
0 голосов
/ 29 ноября 2018

Я прочитал следующее: Размещение новых разрывов, констант и ссылок? и читая слайды от Маттис Крузе на C ++ Встрече Я запутался в отношении следующего кода

struct U { const int i; };
std::vector<U> B;
B.push_back({ 1 });
B.clear();
B.push_back({ 2 });
const int v = B[0].i; // <- Undefined Behavior

B.clear() уничтожает только объекты, а B.push_back({2}) использует размещение нового для создания нового объекта в начале ячейки памяти, выделенной B.

  1. НадеюсьЯ не совсем понимаю, почему доступ B[0].i является неопределенным поведением.
  2. Может ли компилятор кэшировать B[0].i и, возможно, вывести 1?
  3. Что общего с std :: launder?все это?Является ли это инструментом, чтобы действительно гарантировать, что такого рода оптимизации компилятора не могут произойти?

Стандартная реализация libcxx [llvm]:

template <class Tp, class Allocator>
inline typename vector<Tp, Allocator>::reference
vector<Tp, Allocator>::operator[](size_type n)
{
   assert(n < size(), "vector[] index out of bounds");
    return this->__begin_[n];
}

такая же, как на слайдах.

Референции от std 2017:

  • 8.3 (возможное нарушение)
  • 8.4 (упоминание std :: launder)
...