2013-06-24 4 views
5

Могу ли я использовать как л следующий код:Оператор удаления и литья

int main() 
{ 
    int* foo = new int; 
    double* bar = reinterpret_cast<double*>(foo); 
    delete bar; 
} 

ли это UB?

Я думаю, что нам нужно вызвать оператор delete только для указателей, возвращаемых оператором new, но как насчет литья в этом случае?

Я думаю, что это UB, так как reinterpret_cast не дает никаких гарантий относительно полученного указателя. Я прав?

Может ли кто-нибудь опубликовать правильную цитату из стандарта, пожалуйста?

+2

Обратите внимание, что UB здесь находится в выражении удаления, а не в удалении оператора. – PlasmaHH

+0

Хорошо, а как насчет UB здесь? Можете ли вы опубликовать цитату из стандарта, пожалуйста? – FrozenHeart

ответ

6

§5.3.5/2 «В первом варианте (удалить объект), значение операнд удаления может быть нулевым значением указателя, указатель на объект, не являющийся массив, созданные в предыдущем Новом же выражение или указатель на подобъект (1.8), представляющий базовый класс такого объекта (раздел 10). Если нет, поведение не определено ». Так как bar указывает на double, он не указывает на объект , созданный предыдущим новым выражением (которое создало int).

+0

Что такое статический и динамический тип в этом случае? – FrozenHeart

+0

'int' и' double', соответственно. Но даже если формулировка стандарта слишком запутана для понимания, просто подумайте, что вы вызываете неправильный конструктор с тем, что вы делаете. Это должно быть очевидно даже без указанной выше цитаты. Оба деструктора тривиальны, так как это происходит, поэтому оно «будет работать», но это все еще очень очевидно UB. – Damon

+0

@NikitaTrophimov, Подробнее здесь: http://stackoverflow.com/questions/1347691/static-vs-dynamic-type-checking-in-c – chris

0

Здесь вы:

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

Что касается вопросов, что является статическим и динамическим типом:

1.3.7 динамического типа (glvalue)
типа наиболее производным объекта (1.8), к которому glvalue обозначается glvalue выражение ссылается на [Пример: если указатель (8.3.1) p, статический тип которого является «указателем на класс B», указывает на объект класса D, полученный из B (раздел 10), динамический тип выражения * p - «D.». Ссылки (8.3.2) также обрабатываются . -end пример]

1.3.23 статического тип
типа выражения (3.9), в результате анализа программы без учета исполнения семантики [Примечания: Статический тип выражения зависит только от формы программы в котором появляется выражение и не изменяется во время выполнения программы. -end примечание]

+0

. (На самом деле это абзац, который я искал, когда нашел свой ответ.) –

+0

Что такое статический и динамический тип в этом случае? – FrozenHeart

+1

Статический тип - это тип указателя ('double'). Динамический тип - тип pointee ('int'). –

2

От 5.3.5-3:

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

Оставив в стороне возможные проблемы с использованием reinterpret_cast здесь, это UB, потому что типы не совпадают. Представьте себе какой-то нетривиальный тип, тогда вы можете легко увидеть это, поскольку будет вызван «неправильный» dtor.

Кроме того, используя результат reinterpret_cast для чего-либо другого, кроме того, что его отлитие в основном не указано стандартом.

+0

Что такое статический и динамический тип в этом случае? – FrozenHeart

+1

@NikitaTrophimov: динамический тип объекта - это int, поскольку объект был создан как int, а static выражения - double, поскольку вы рассматриваете вещь как двойную в этой точке. – PlasmaHH

+0

У вас другое мнение, чем ребята из других ответов :) – FrozenHeart