Hi I'm trying to read a byte array into a struct and the bytes are coming out in the reverse order (to how i expected). Can someone help me understand whats happening please?
unsigned char buf[] = {
0x11, 0x22, 0x33, 0x44,
0x55, 0x66, 0x77, 0x88,
0x99, 0xaa, 0xbb, 0xcc
};
typedef struct mystruct {
uint16_t var1;
uint16_t var2;
uint32_t var3;
uint32_t var4;
} something;
int main(int argc,char **argv){
printf("sizeof buf: %lu %d \n",sizeof(buf),sizeof(something));
something *st = (something*)&(buf[0]);
#define pr(a) printf(#a" %x\n",a)
pr(st->var1);
pr(st->var2);
pr(st->var3);
pr(st->var4);
return(0);
}
Output:
sizeof buf: 12 12
st->var1 2211
st->var2 4433
st->var3 88776655
st->var4 ccbbaa99
I was expecting something like: st->var1 1122
Doing this also seems to output the same thing?
memcpy(&st->var1,buf,2);
pr(st->var1);
output: st->var1 2211
x86/Linux server, gcc version 4.5.3 (if that helps)
Thanks for your help.
If you read about endianness, you will see that there are two ways of storing data longer than one byte in memory.
For big-endian systems (like ARM), the integer value 0x1122
is stored in memory as (from lower to higher addresses) 0x11 0x22
. On a little-endian system (like x86) it's stored as 0x22 0x11
.
As your data in the array is stored "big-endian", you get the opposite byte ordering to what you expect on a little-endian system like yours.
As others have pointed out your main observable issue is that one of edianness.
Your method for accessing buf
is undefined behavior because it violates strict aliasing rules here by type punning here:
something *st = (something*)&(buf[0]);
If I built this code on using gcc
using the following arguments:
-O3 --Wstrict-aliasing=2
I receive the following warning:
main.cpp:22:4: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
something *st = (something*)&(buf[0]);
^
I am currently using version 4.8
. The relevant section from the C11 draft standard that covers aliasing rules is 6.5/7
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With