Is placement new of derived object within a vector / array defined to be base object legal
#include <iostream>
#include <memory>
#include <vector>
struct A
{
virtual ~A()
{
std::cout << "~A()" << std::endl;
}
};
struct B : public A
{
virtual ~B()
{
std::cout << "~B()" << std::endl;
}
};
int main()
{
std::vector<A> a(1);
a[0].~A();
:: new(std::addressof(a[0])) B();
}
Is this legal C++?
The question is related to the one here. The gist of the discussion there is that we are able to determine the type of the objects in a vector / array at compile time and so we do not have to do any dynamic dispatch. We can use this information to optimize whatever gcc is doing right now.
I filed an issue with gcc here and the argument against this optimization is that we could potentially have placement new changing the type stored in the vector / array, but we aren't sure if it is legal, hence this stackoverflow question.
Interestingly, gcc behaves differently from clang for arrays, and gcc has a different behavior with itself depending on the length of the array. It does the virtual dtor when len >= 3 but qualified dtor call when len < 3.
https://godbolt.org/z/f33Gh5EGM
Edit:
The question is purely "Is this legal C++". Any other information in the question is for context on why I'm asking such a question.