Search code examples
cmemorystructunions

memory order of structs and ints


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.


Solution

  • 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.