Pregunta

Por ejemplo, si declaro una variable larga, ¿puedo asumir que siempre estará alineada en un límite "tamaño de (largo)"?La ayuda en línea de Microsoft Visual C++ lo dice, pero ¿es un comportamiento estándar?

algo más de información:

a.Es posible crear explícitamente un entero desalineado (*barra):

char foo[5]

int * barra = (int *)(&foo[1]);

b.Aparentemente, #pragma pack() solo afecta a estructuras, clases y uniones.

C.La documentación de MSVC indica que los tipos de POD están alineados con sus respectivos tamaños (pero es siempre o de forma predeterminada, y es un comportamiento estándar, no lo sé)

¿Fue útil?

Solución

Como otros han mencionado, esto no es parte del estándar y queda en manos del compilador implementarlo como mejor le parezca para el procesador en cuestión.Por ejemplo, VC podría implementar fácilmente requisitos de alineación diferentes para un procesador ARM que para los procesadores x86.

Microsoft VC implementa lo que básicamente se llama alineación natural hasta el tamaño especificado por la directiva #pragma pack o la opción de línea de comando /Zp.Esto significa que, por ejemplo, cualquier tipo de POD con un tamaño menor o igual a 8 bytes se alineará en función de su tamaño.Cualquier valor mayor se alineará en un límite de 8 bytes.

Si es importante controlar la alineación para diferentes procesadores y diferentes compiladores, entonces puede usar un tamaño de paquete de 1 y rellenar sus estructuras.

#pragma pack(push)
#pragma pack(1)    
struct Example
{
   short data1;     // offset 0
   short padding1;  // offset 2
   long data2;      // offset 4
};
#pragma pack(pop)

En este código, el padding1 La variable existe solo para garantizar que data2 esté alineado naturalmente.

Responder a una:

Sí, eso puede provocar fácilmente datos desalineados.En un procesador x86, esto no duele mucho.En otros procesadores, esto puede provocar un fallo o una ejecución muy lenta.Por ejemplo, el procesador Alpha generaría una excepción de procesador que el sistema operativo detectaría.Luego, el sistema operativo inspeccionaría la instrucción y luego haría el trabajo necesario para manejar los datos desalineados.Luego continúa la ejecución.El __unaligned La palabra clave se puede utilizar en VC para marcar el acceso no alineado para programas que no sean x86 (es decir,fuerza).

Otros consejos

Por defecto, sí.Sin embargo, se puede cambiar mediante pack() #pragma.

No creo que el estándar C++ establezca ningún requisito a este respecto y lo deja en manos de la implementación.

C y C++ no exigen ningún tipo de alineación.Pero x86 prefiere la alineación natural y es requerido por la mayoría de las otras arquitecturas de CPU, y los compiladores generalmente hacen todo lo posible para mantener contentas a las CPU.Entonces, en la práctica, no verá que un compilador genere datos desalineados a menos que realmente le gire el brazo.

Sí, todos los tipos siempre están alineados al menos con sus requisitos de alineación.

¿Cómo podría ser de otra manera?

Pero tenga en cuenta que el tamaño de () un tipo no es lo mismo que su alineación.

Puede utilizar la siguiente macro para determinar los requisitos de alineación de un tipo:

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )

Depende del compilador, los pragmas y el nivel de optimización.Con los compiladores modernos también puedes elegir la optimización del tiempo o del espacio, lo que también podría cambiar la alineación de los tipos.

Generalmente será porque leer/escribir es más rápido de esa manera.Pero casi todos los compiladores tienen un interruptor para desactivar esto.En gcc es -maligno-???.En el caso de los agregados, generalmente se alinean y dimensionan en función de los requisitos de alineación de cada elemento que los contiene.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top