I want to make a union with a struct and and a uint64_t, so I can reference individual uint16_ts with the struct, and have them be concatenated in the uint64_t. I made this test program:
#include "stdio.h"
#include "stdint.h"
struct test_struct{
uint16_t stuff;
uint16_t a;
uint16_t b;
uint16_t c;
};
union test_union{
struct test_struct str;
uint64_t uint;
};
int main(){
struct test_struct x = {
.stuff = 0x0000,
.a = 0x1234,
.b = 0x5678,
.c = 0x9ABC
};
union test_union y;
y.str = x;
printf("y.uint: %llX\n", y.uint);
}
The output becomes:
y.uint: 9ABC567812340000
which is counter-intuitive to me (it shoud be 0000123456789ABC, or 123456789ABC). Can someone explain to me why the elements in the struct seem to be reversed?
EDIT: For future reference: The endianness answers had me confused, because, the uint16_ts were printed in the right order. But this is, of course, because they themselves are stored little-endian.
You are on a little-endian platform, and the bytes stored first (with the lowest addresses) end up in the least significant bits (right-hand side when printed) of the combined uint64_t
.
If you run the same code on a big-endian platform, you would get the result you expect. Your code as it stands is not portable across systems with different endianness.