Базовый указатель на массив производных объектов

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

struct Base
{
  int member;
};

struct Derived : Base
{
  int another_member;
};

int main()
{
  Base* p = new Derived[10]; // (1)
  p[1].member = 42; // (2)
  delete[] p; // (3)
}

Согласно стандарту ] (1) правильно сформирован, потому что Dervied * (который является результатом new-expression ) может быть неявно преобразован в Base * (Черновик C ++ 11, §4.10 / 3):

Prvalue типа «указатель на cv D», где D - тип класса, может быть преобразовано в prvalue типа «указатель на cv B», где B - основание класс (пункт 10) D. Если B недоступен (пункт 11) или неоднозначный (10.2) базовый класс D, программа, которая требует этого преобразование плохо сформировано. Результатом преобразования является указатель на подобъект базового класса объекта производного класса. Нулевой указатель значение преобразуется в значение нулевого указателя целевого типа.

(3) приводит к неопределенному поведению из-за §5.3.5 / 3:

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

Является ли (2) законным в соответствии со стандартом или это приводит к некорректной программе или неопределенному поведению?

edit: Лучшая формулировка

11
задан Community 23 May 2017 в 11:43
поделиться