Следуя question, заданному здесь ранее сегодня, и множеству аналогичных тематических вопросов, я здесь, чтобы спросить об этой проблеме с точки зрения stadard.
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*
(который является результатом нового выражения) может быть неявно преобразован в Base*
(С++ 11 draft, §4.10/3):
Значение типа "указатель на cv D", где D - тип класса, может быть преобразуется в prvalue типа "указатель на cv B", где B является базой класса (пункт 10) D. Если B является недоступным (пункт 11) или двусмысленный (10.2) базовый класс D, программа, которая требует этого преобразование плохо сформировано. Результатом преобразования является указатель на субобъект базового класса объекта производного класса. Нулевой указатель значение преобразуется в значение нулевого указателя для типа адресата.
(3)
приводит к поведению undefined из-за §5.3.5/3:
В первом альтернативе (удалить объект), если статический тип объект, подлежащий удалению, отличается от его динамического типа, статический тип должен быть базовым классом динамического типа объекта, который должен быть и статический тип должен иметь виртуальный деструктор или поведение undefined. Во втором альтернативе (удалить массив), если динамический тип подлежащего удалению объекта отличается от его статического типа, поведение undefined.
Является ли (2)
законным в соответствии со стандартом или это приводит к неправильной программе или поведению undefined?
edit: Лучшая формулировка