IsoCpp.org предлагает FAQ относительно размещения нового:Строгие Aliasing Правило и размещение Нового
примера они обеспечивают:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal
// ...
}
бы не выше код нарушает строгое правило сглаживания C++ 's начиная с place
и memory
- это разные типы, но ссылки на одну и ту же ячейку памяти?
(я знаю, что указатели типа char
может псевдоним любого другого типа, но здесь мы, кажется, есть void*
альясинга в char*
, который не имеет права от того, что я понимаю?)
Я подозреваю, что большинство распределителей памяти также будет нарушать правило строгого псевдонимов аналогичным образом. Каков надлежащий способ соблюдения правила строгого сглаживания при использовании нового места размещения?
Спасибо
Стандарт фактически делает исключение для указателей 'char' в строгом сглаживании. Поскольку они используются так часто, чтобы сделать буферы точного размера для хранения различных структур и еще чего-то, компиляторы должны предполагать, что любой другой указатель может иметь псевдоним 'char *'. Учитывая, что 'void *' не может быть отсрочен, в общем случае компиляторы будут жаловаться только на то, что если вы укажете указатель void на другой тип и используете его, вы можете столкнуться с проблемами псевдонимов. Ваша основная проблема - сглаживание 'memory' и' f', но при условии, что 'memory' является' char * ', вы в порядке. – RyanP
@ RyanP, спасибо за разъяснение; Я совершенно новичок в строгом псевдониме и не понимал, что на самом деле нужно разыгрывать UB. Я знал об исключении 'char *' aliasing, но я думал, что он пошел только в одну сторону. Значит, 'char *' может использовать псевдоним (и deref) любого типа 'T', но тип' T' может быть только псевдонимом и deref тип 'char *', если 'T' сам имеет тип' char * '? – digitale