Действительно ли новый символ гарантирует выровненную память для типа класса?


выделяет буфер через new char[sizeof(T)] гарантированно выделить память, которая правильно выровнена для типа T, где все члены T имеет свою естественную, определенную реализацию, выравнивание (то есть вы не использовали alignas ключевое слово для изменения их выравнивания).

Я видел эту гарантию, сделанную в нескольких ответах здесь, но я не совсем понимаю, как стандарт приходит к этой гарантии. 5.3.4-10 Стандарта дает основное требование: по существу new char[] должен быть согласован с max_align_t.

то, что мне не хватает, это бит, который говорит alignof(T) всегда будет действительным выравнивание с максимальным значением max_align_t. Я имею в виду, это кажется очевидным, но в результате выравнивания структуры быть не более max_align_t? Даже в пункте 3.11-3 говорится, что расширенные выравнивания могут поддерживаться, поэтому компилятор может самостоятельно решить, что класс является чрезмерно выровненным типом?

2 53

2 ответа:

чего мне не хватает-это бит, который говорит alignof(T) всегда будет допустимым выравнивание с максимальным значением max_align_t. Я имею в виду, это кажется очевидным, но в результате выравнивания структуры быть не более max_align_t ? Даже в пункте 3.11-3 говорится, что расширенные выравнивания могут поддерживаться, поэтому компилятор может самостоятельно решить, что класс является чрезмерно выровненным типом ?

как отметил Манкарс, лучшая цитата, которую я мог бы получить, - это [basic.align] / 3:

тип, имеющий расширенное требование выравнивания, является чрезмерно выровненным типом. [ Отмечать: каждый чрезмерно выровненный тип является или содержит тип класса, к которому применяется расширенное выравнивание (возможно, через нестатический элемент данных). -конец Примечание ]

что, по-видимому, подразумевает, что расширенное выравнивание должно быть явно обязательным (а затем распространяется), но не может

Я бы предпочел более четкое упоминание; намерение очевидно для компилятора-писателя и любое другое поведение было бы безумным, все же...

выражения new char[N] и new unsigned char[N] гарантированно для возврата памяти достаточно выровнять по любому объекту. См. §5.3.4/10 "[...] Для массивов char и unsigned char, разница между результат нового выражения и адрес, возвращенный распределением функция должна быть интегральной кратной самой строгой фундаментальной требование выравнивания (3.11) любого типа объекта, размер которого не больше чем размер создаваемого массива. [ Примечание: потому что распределение функции предполагается возвращать указатели на хранилище, которое является соответствующим образом выровнены для объектов любого типа с основными выравнивание, это ограничение на накладные расходы распределения массива позволяет общая идиома выделения символьных массивов, в которые входят объекты других типы будут размещены позже. - конец Примечания ]".

со стилистической точки зрения, конечно: если то, что вы хотите, чтобы выделить raw память, яснее сказать так:operator new(N). Концептуально, new char[N] создает Nchar;operator new(N) выделяет N байт.