Почему на самом деле удаление неполного типа является неопределенным поведением?

Рассмотрим этот классический пример, используемый для объяснения того, чтоне делать с предварительными декларациями:

//in Handle.h file
class Body;

class Handle
{
   public:
      Handle();
      ~Handle() {delete impl_;}
   //....
   private:
      Body *impl_;
};

//---------------------------------------
//in Handle.cpp file

#include "Handle.h"

class Body 
{
  //Non-trivial destructor here
    public:
       ~Body () {//Do a lot of things...}
};

Handle::Handle () : impl_(new Body) {}

//---------------------------------------
//in Handle_user.cpp client code:

#include "Handle.h"

//... in some function... 
{
    Handle handleObj;

    //Do smtg with handleObj...

    //handleObj now reaches end-of-life, and BUM: Undefined behaviour
} 

Из стандарта я понимаю, что этот случай направлен в сторону UB, поскольку деструктор Body не тривиален. То, что я пытаюсь понять, действительно является коренной причиной этого.

Я имею в виду, что проблема, похоже, «вызвана» тем фактом, что dtor в Handle является встроенным, и поэтому компилятор делает что-то вроде следующего «встроенного расширения» (здесь почти псевдокод).

inline Handle::~Handle()
{
     impl_->~Body();
     operator delete (impl_);
}

Во всех единицах перевода (толькоHandle_user.cpp в данном случае) где экземпляр Handle будет уничтожен, верно? Я просто не могу этого понять: хорошо, при генерации вышеупомянутого встроенного расширения у компилятора нет полного определения класса Body, но почему он не может просто разрешить компоновщик дляimpl_->~Body() и так ли это вызвать функцию деструктора Body, которая на самом деле определена в его файле реализации?

Другими словами: я понимаю, что в момент уничтожения дескриптора компилятор даже не знает, существует (нетривиальный) деструктор для Body или нет, но почему он не может сделать так, как всегда, то есть оставить "заполнитель" для компоновщика, чтобы заполнить, и в конечном итоге иметь компоновщик "неразрешенный внешний", если эта функция действительно недоступна?

Я что-то упустил здесь (и в таком случае извините за глупый вопрос)? Если это не так, мне просто любопытно понять причину этого.

Ответы на вопрос(6)

Ваш ответ на вопрос