alineación de memoria __attribute __ ((alineado (8)))

Tengo un progtwig en un libro

#include  int main( ) { struct data { int a __attribute__( ( aligned ( 8 ) ) ) ; char ch __attribute__( ( aligned ( 1 ) ) ) ; float s __attribute__( ( aligned ( 4 ) ) ) ; } ; struct data e ; printf ( "\n%u %u %u", &e.a, &e.ch, &e.s ) ; printf ( "\n%d", sizeof ( e ) ) ; return 0 ; } 

cuando lo ejecuto en cygwin instalado en la máquina con Windows 7. Estoy obteniendo salida

2280712 2280716 2280720 16

¿Por qué esta salida que estoy recibiendo? Esperaba la salida

2280712 2280720 2280721 13

Un sizeof es siempre un múltiplo de la alineación más grande, ya que en realidad se informa de ‘paso’ en caracteres en una matriz del tipo dado que incluye relleno entre los miembros, por lo que el relleno entre los elementos de la matriz es necesario para alinearlos.

El diseño de memoria de los struct data de struct data se verá así:

  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 ... <--offset | | | struct data (element [0]) | (element [1]) | | | a |ch|::::::::| s |:::::::::::| a |ch|::::... | | |<----------- sizeof(struct data) ------------->| |::::| is padding 
  • a está en el desplazamiento 0, que obviamente es un múltiplo de 8;
  • ch está en el desplazamiento 4, que es (también obviamente) un múltiplo de 1;
  • s está en el desplazamiento 8, que es múltiplo de 4;
  • sizeof(struct data) es igual a la desviación de [1] (16) que requiere ser múltiplo de max(8,1,4) = 8

El atributo aligned(N) alinea el elemento de datos actual en una dirección que es un múltiplo de N , insertando bytes de relleno antes del elemento de datos. Parece que esperas que haga algo con el embalaje, que es diferente.

Su estructura parece estar dispuesta de la siguiente manera:

 Address Member ------- ------- 2280712 a [address aligned on multiple of 8] 2280713 a 2280714 a 2280715 a 2280716 ch [address aligned on multiple of 1] 2280717 (unused) 2280718 (unused) 2280719 (unused) 2280720 s [address aligned on multiple of 4] 2280721 s 2280722 s 2280723 s 

alineado (8) solo significa que la dirección de & e.a se alineará con 8. Y es (2280712). sizeof (int) es presumiblemente 4, por lo que su char termina en 2280716 (tiene un requisito de alineación de 1, por lo que no hay razón para que sea empujado a 2280720). Solo agregue sizeof (int) a su salida de depuración para verificarlo.

Deberá cambiar la configuración de destino de la comstackción si desea usar ints de 64 bits.