Distruttore virtuale e comportamento indefinito

Questa domanda è diversa da ‘ Quando / perché dovrei usare un distruttore virtual ? ‘.

 struct B { virtual void foo (); ~B() {} // <--- not virtual }; struct D : B { virtual void foo (); ~D() {} }; B *p = new D; delete p; // D::~D() is not called 

Domande :

  1. Questo può essere classificato come un comportamento indefinito (siamo consapevoli che ~D() non sarà sicuramente chiamato)?
  2. Cosa succede se ~D() è vuoto. Influirà il codice in qualche modo?
  3. Usando new[] / delete[] con B* p; , il ~D() verrà sicuramente chiamato, indipendentemente dalla virtual del distruttore. È un comportamento indefinito o un comportamento ben definito?