Действительно ли новый символ гарантирует выровненную память для типа класса?
выделяет буфер через 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 ответа:
чего мне не хватает-это бит, который говорит
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байт.