En travaillant sur certaines structures de cadres, je suis tombé sur un comportement étrange. Je l'ai testé rapidement et le code d'échantillon indépendant avec ce qui suit:Bizarre struct packing
struct non_alligned_struct
{
uint8_t flag;
// start of uint32 bit fields
uint32_t a:2;
uint32_t b:2;
uint32_t c:1;
uint32_t d:1;
uint32_t e:1;
uint32_t f:1;
uint32_t g:3;
uint32_t h:1;
uint32_t i:1;
uint32_t j:3;
uint32_t k:3;
uint32_t l:1;
uint32_t m:1;
uint32_t n:1;
uint32_t o:1;
uint32_t p:3;
uint32_t q:2;
uint32_t r:1;
uint32_t s:1;
uint32_t t:2;
//4 bytes ends here
// shouldn't this start at 5th byte ??
uint16_t u;
uint16_t v:13;
uint16_t w:3;
uint16_t x;
uint16_t y:13;
uint16_t z:3;
};
int main()
{
struct non_alligned_struct obj1;
void *ptr1 = &obj1;
void *ptr2 = &(obj1.u);
printf("ptr1: %p, ptr2: %p, ptr2 - ptr1: %d\n", ptr1, ptr2, ptr2 - ptr1);
return 0;
}
Sortie: ptr1: 0x7fff3216a620, ptr2: 0x7fff3216a626, ptr2 - ptr1: 6
Question: Pourquoi ptr2 - ptr1 devrait être 6. Selon mes calculs, cela aurait dû être 5. De plus, la structure est de 13 octets, donc 4 octets sont alignés et le remplissage est fait de façon bizarre. Je vérifié en donnant des valeurs aléatoires pour les variables membres et je constate que le rembourrage est réalisé en suivant endroits gras
00000000: 01 22 31 10 67 fe 86 01 fe ff 86 01
ptr2-ptr1 est égal à 6 ... – DigitalNinja
En MSVC si je joins le 'struct' avec' #pragma pack (push, 1) 'et' #pragma pack (pop) 'il donne le résultat attendu' 5' , autrement '8'. J'ai dû changer les pointeurs 'void *' en 'char *' car l'arithmétique du pointeur sur les types 'void *' est définie par l'implémentation. –
Violation de contrainte faisant de l'arithmétique sur 'void *' s. Votre compilateur était obligé d'émettre un diagnostic pour cette erreur. – EOF