c - Structure Alignment when Accessed by Pointer -


when accessing structure byte stream (file, network, etc...) alignment mean?

for example, can understand why compiler want pad following structure bytes align int , short b @ word addresses (multiples of 4). however, mean when accessing memory @ random address via using pointer? using -> operator generate inefficient code? or missing something?

typedef struct{     void*   ptr;  //4 bytes     char    c1;   //1 byte     int     a;    //4 bytes     char    c2;   //1 byte     short   b;    //2 byte     char    c3;   //1 byte } odd_struct;     //minimum needed = 13 bytes, actual (with padding) = 20  unsigned char buffer[128]; odd_struct odd_struct;  odd_struct.a = 123456789; odd_struct.b = 12345;  printf("sizeof(odd_struct): %d\n", sizeof(odd_struct));  memcpy(buffer+3, &odd_struct, sizeof(odd_struct));  odd_struct* testptr = (odd_struct*)(buffer+3);  printf("testptr->a: %d\n", testptr->a); printf("testptr->b: %d\n", testptr->b); 

and output

sizeof(odd_struct): 20 testptr->a: 123456789 testptr->b: 12345 

to answer why want this:

i intending use system limited ram, it's tempting cast byte (unsigned char) pointer struct pointer , access way. without additional copy of memory. i.e. use bytes in place. working fine on x86 pc using gcc. based on comments below, seems might bad idea.

alignment means implementation may place restriction on addresses @ can access or point object of type. this page describes why processors might make restriction in order improve performance.

you can inspect alignment requirement of type (since c11) checking _alignof(odd_struct).

if not equal1, code (odd_struct*)(buffer+3) may cause undefined behaviour. whether or not cause ub depends on whether buffer+3 happens multiple of alignment requirement.

the following code correct (well - technically possibility exists not, standard intends uintptr_t behave sensibly):

int req = _alignof(odd_struct); if ((uintptr_t)(buffer+3) % req)     printf("would undefined behaviour.\n"); else {     odd_struct* testptr = (odd_struct*)(buffer+3);      printf("testptr->a: %d\n", testptr->a);     printf("testptr->b: %d\n", testptr->b); } 

in theory compiler detect potential unaligned access , generate different assembly code simulate accessing value intend. don't know of compiler though.

typically compiler assume access correctly aligned , generate right assembly case only. behaviour depend on processor. example, typically arm cpus cause hardware trap unaligned access, , intel cpus implement access in hardware using slower technique, described on page linked earlier.

some cpus might trap or silently load incorrect address try load unaligned address address register.

to write robust code should make no assumptions how undefined behaviour might manifest itself; instead, avoid writing code undefined behaviour in first place.


Comments

Popular posts from this blog

Django REST Framework perform_create: You cannot call `.save()` after accessing `serializer.data` -

Why does Go error when trying to marshal this JSON? -