2011-12-07 9 views
5

De acuerdo con MSDN, el comando /Zp tiene como valor predeterminado 8, lo que significa que se usan los límites de alineación de 64 bits. Siempre he supuesto que para las aplicaciones de 32 bits, el compilador de MSVC usará límites de 32 bits. Por ejemplo:Alineación de memoria predeterminada de MSVC de 8

struct Test 
{ 
    char foo; 
    int bar; 
}; 

La almohadilla compilador que de este modo:

struct Test 
{ 
    char foo; 
    char padding[3]; 
    int bar; 
}; 

lo tanto, ya /Zp8 Se utiliza por defecto, ¿significa que mi acolchado se convierte en 7 + 4 bytes utilizando el mismo ejemplo anterior:

struct Test 
{ 
    char foo; 
    char padding1[7]; 
    int bar; 
    char padding2[4]; 
}; // Structure has 16 bytes, ending on an 8-byte boundary 

Esto es un poco ridículo ¿no? ¿Estoy malentendido? ¿Por qué se usa un relleno tan grande? Parece una pérdida de espacio. La mayoría de los tipos en un sistema de 32 bits ni siquiera van a usar 64 bits, por lo que la mayoría de las variables tendrían relleno (probablemente más del 80%).

+0

¿Puedes aclarar sobre el '7 + 4'? Estoy algo confundido por la pregunta en este momento. – Mysticial

+0

@Mysticial: Actualicé mi OP con otro ejemplo para mostrarle lo que quiero decir con eso. Perdón por la confusion. –

+0

Gracias por la aclaración. Acabo de probar tu primera estructura y el tamaño es de solo 8 bytes, rellenado a través del segundo fragmento de estructura. Por lo tanto, no puedo reproducir lo que obtienes. (o al menos lo que crees que deberías estar recibiendo) – Mysticial

Respuesta

8

Así no es como funciona. Los miembros están alineados con un múltiplo de su tamaño. Char a 1 byte, corto a 2, int a 4, double a 8. La estructura está acolchada al final para asegurar que los miembros aún se alineen correctamente cuando la estructura se usa en una matriz.

Un embalaje de 8 significa que deja de intentar alinear los miembros que son más grandes que 8. Lo cual es un límite práctico, el asignador de memoria no devuelve las direcciones alineadas mejor que 8. Y el doble es brutalmente caro si no lo es alineado correctamente y termina a horcajadas sobre una línea de caché. Pero de lo contrario, un dolor de cabeza si escribe código SIMD, requiere una alineación de 16 bytes.

+0

Entonces, dado que la alineación predeterminada es 8 según MSDN, ¿a qué se parece el relleno de alineación al último fragmento de código en mi OP? Si no, por favor explique. –

+1

@Robert: Su último código es incorrecto. Se rellenará como este 'char foo; pad [3]; int bar; 'Porque' int' es el miembro más grande en la estructura. Debes leer muy cuidadosamente lo que dijo Hans – Benjamin

3

Eso no significa cada miembro está alineado en un límite de 8 bytes. Lea un poco más atentamente:

the smaller member type or n-byte boundaries 

La clave aquí es la primera parte - "tipo de miembro más pequeño". Eso significa que los miembros con menos alineación podrían alinearse menos, de manera efectiva.

struct x { 
    char c; 
    int y; 
}; 
std::cout << sizeof(x); 
std::cout << "offsetof(x, c) = " << offsetof(x, c) << '\n'; 
std::cout << "offsetof(x, c) = " << offsetof(x, y) << '\n'; 

Esto produce 8, 0, 4- significado que, de hecho, la int solamente se rellena hasta una alineación 4byte.

+1

La última parte de tu respuesta es incorrecta. Elimine el int de la estructura y tenga en cuenta que sizeof() no devuelve 8. –

Cuestiones relacionadas