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
Post a Comment