0

I have read the following: Placement new breaks consts and references? and by reading the slides from Matthis Kruse at the C++ Meeting I am confused regarding the following code

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() only destructs the objects, and B.push_back({2}) uses placement new to construct a new object at the start of the memory location B has allocated.

  1. I don't understand quite why the access B[0].i is undefined behavior.
  2. Could the compiler have cached B[0].i and possibly output 1?
  3. What has std::launder to do with all this? Is it a tool to really make sure these kind of compiler optimizations cannot happen?

The standard libcxx [llvm] implementation:

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];
}

is the same as in the slides.

References from std 2017:

  • 8.3 (Possible violation)
  • 8.4 (mentioning std::launder)
Gabriel
  • 8,141
  • 5
  • 49
  • 95
  • 2
    This seems like a near duplicate of [How does std::launder affect containers?](https://stackoverflow.com/q/40165022/364696). – ShadowRanger Nov 28 '18 at 23:33
  • 1
    My answer to [Implementing a std::vector like container without undefined behavior](https://stackoverflow.com/a/52997191/1708801) may explain some of the details. – Shafik Yaghmour Nov 29 '18 at 03:00

0 Answers0