Following up the p0532r0.pdf documentation the following piece of code results in UB
#include <iostream>
#include <vector>
struct X {
const int i;
X(int _i) : i(_i) {}
friend std::ostream& operator<< (std::ostream& os, const X& x) {
return os << x.i;
};
};
int main(){
std::vector<X> v;
v.push_back(X(42));
v.clear();
v.push_back(X(77));
std::cout << v[0]; // undefined behaviour
}
However no UB is detected when the above piece of code is run with sanitiser. demo Why does compiler not detect this error? Apart from that based on the P0532R0, when type of vector is a class that has a const member , the internal usage of placement new causes UB. How is this issue overcome ?
the internal usage of placement new causes UB
If the compiler uses placement new to overwrite the vector's first element this is no longer UB as of C++ 20. Placement new is allowed to "transparently replace" const values so long as it is not a top level const. Also, std::launder
is no longer needed for access. See basic life for details on transparent replacement.
However, the copy assignment operator is automatically deleted so the vector object can no longer be resized for instance by adding additional elements that exceed the vector's capacity.
See this discussion on how to write a custom copy assigment operator to handle classes with const or reference objects.