Here on SO we have had a lot of questions about assignments to const fields and Undefined Behavior (UB). For example This accepted answer which says that is not possible to define a copy assignment operator for classes with const fields because of UB.
But I checked the current draft version of the C++ standard (N4861). The part which said it would be UB [basic.life.8] was:
If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:...
the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
Has now been replaced with:
o1 is not a complete const object, and
My interpretation is, that the following code now has no UB. Is it right? I ask this because in the sample, there is no cv qualified member - so it's still not clear for me.
#include <iostream>
struct C {
const int i;
void f() const {
std::cout << i << "\n";
}
C(int i) : i(i) {}
C& operator=( const C& );
};
C& C::operator=( const C& other) {
if ( this != &other ) {
this->~C(); // lifetime of *this ends
new (this) C(other); // new object of type C created
f(); // well-defined
}
return *this;
}
int main(){
C c1(1);
C c2(2);
c1 = c2; // well-defined
c1.f();
}
In fact my observation is that it works with all major compilers but that makes it not legal...