c++ c++11 language-lawyer

c++ - ¿El nuevo carácter en realidad garantiza la memoria alineada para un tipo de clase?



c++11 language-lawyer (2)

Está asignando un búfer a través del new char[sizeof(T)] garantizado para asignar memoria que se alinea correctamente para el tipo T , donde todos los miembros de T tienen su alineación natural, definida por la implementación (es decir, no ha utilizado la palabra clave alignas para modificar su alineación).

He visto esta garantía en algunas respuestas por aquí, pero no estoy del todo claro cómo llega la norma a esta garantía. 5.3.4-10 de la norma proporciona el requisito básico: esencialmente new char[] debe estar alineado con max_align_t .

Lo que me falta es el bit que dice que alignof(T) siempre será una alineación válida con un valor máximo de max_align_t . Quiero decir, parece obvio, pero ¿la alineación resultante de una estructura debe ser como máximo max_align_t ? Incluso el punto 3.11-3 dice que las alineaciones extendidas pueden ser soportadas, entonces ¿el compilador puede decidir por sí mismo que una clase es un tipo sobrealineado?


Lo que me falta es el bit que dice que alignof(T) siempre será una alineación válida con un valor máximo de max_align_t . Quiero decir, parece obvio, pero ¿la alineación resultante de una estructura debe ser como máximo max_align_t ? Incluso el punto 3.11-3 dice que las alineaciones extendidas pueden ser soportadas, entonces ¿el compilador puede decidir por sí mismo que una clase es un tipo sobrealineado?

Como señaló Mankarse, la mejor cita que pude obtener es de [basic.align] / 3 :

Un tipo que tiene un requisito de alineación extendida es un tipo sobrealineado. [Nota: cada tipo sobrealineado es o contiene un tipo de clase al que se aplica la alineación extendida (posiblemente a través de un miembro de datos no estáticos). -finalizar nota]

lo que parece implicar que la alineación extendida debe ser explícitamente requerida (y luego propagada) pero no puede

Hubiera preferido una mención más clara; la intención es obvia para un compilador-escritor, y cualquier otro comportamiento sería una locura, aún así ...


Se garantiza que las expresiones new char[N] y new unsigned char[N] devuelvan la memoria suficientemente alineada para cualquier objeto. Ver §5.3.4 / 10 "[...] Para matrices de char y char sin signo, la diferencia entre el resultado de la nueva expresión y la dirección devuelta por la función de asignación será un múltiplo integral del requisito de alineación fundamental más estricto. (3.11) de cualquier tipo de objeto cuyo tamaño no sea mayor que el tamaño de la matriz que se está creando. [Nota: como se supone que las funciones de asignación devuelven los punteros al almacenamiento que está apropiadamente alineado para los objetos de cualquier tipo con alineamiento fundamental, esta restricción en la sobrecarga de asignación de matrices permite la expresión común de la asignación de matrices de caracteres en las que posteriormente se colocarán objetos de otros tipos. -finalizar nota] ".

Desde un punto de vista estilístico, por supuesto: si lo que quiere es asignar memoria bruta, es más claro decirlo: operator new(N) . Conceptualmente, el new char[N] crea N char ; operator new(N) asigna N bytes.