Как новое размещение узнает, какой макет создать?

#include <iostream>
#include <typeinfo>
struct A { int a; };
struct B : virtual A { int b; };
struct C : virtual A  { int c; };
struct D : B,C { int d; };
int main()
{
  D complete;
  B contiguous;
  B & separate = complete;
  B * p[2] = {&separate, &contiguous};
  // two possible layouts for B: 
  std::cout<< (int)((char*)(void*) &p[0]->a -(char*)(void*)&p[0]->b)<<" "<< sizeof(*p[0])<< "\n";
  std::cout<< (int)((char*)(void*) &p[1]->a -(char*)(void*)&p[1]->b)<<" "<< sizeof(*p[1])<< "\n";

  alignas(B) char buff[sizeof(B)];
  void * storage = static_cast<void*>(buff);
  // new expression skips allocation function:
  auto pointer= new (storage) B;        // Which layout to create?
  std::cout << typeid(pointer).name()<<"\n"; 
  pointer->~B();    // Destructor knows layout through typed pointer.
}
// sample output (Debian 8, amd64):
// 24 16
// 4 16
// P1B

Есть ли раздел вСтандарт C ++ 14 что требует «нового» для создания определенного макета? Есть ли гарантия, что созданный новый макет помещается в буфер размера sizeof (B) и со смещением ноль?

редактировать: не могли бы вы использовать grep-friendly терминологию или предоставить ссылки? Я добавил ссылку на стандарт на вопрос.

Примите во внимание приведенный выше пример вывода: что говорит вам число 24? Какой размер буфера?

В стандарте может быть утверждение, что наиболее производный объект всегда является прямой непрерывной копией представления объекта, но я не нашел этого.

Что мы знаем о новом, так это то, что он должен использоваться с полным типом объекта. [Expr.new]

Есть пример для выражения new с опцией размещения в [class.dtor] §12.4 (14). Однако пример может сработать просто потому, что класс в нем имеет стандартную компоновку.

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

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