10 years, 9 months ago.

Union of a uint64_t and uint8_t[8] - array gives different endian

I've been looking into using a union of a uint64_t and a byte array. Idea is I can pass the array to a function to send to a device over serial, and be able to implement a LSFR on the uint64.

I have declared the union as follows:

Union

static union
{
    uint8_t KEY_ARR[8];
    uint64_t KEY_LONG;   
} Key_Union;

Then doing:

Key_Union.KEY_LONG = 0x0123456789abc;
pc.printf("\n\r{");
for(int i = 0; i < 8; i++){ //print the array
    pc.printf("%02x", Key_Union.KEY_ARR[i]);
}
pc.printf("}");
pc.printf("\n\r%x%x", (int)(Key_Union.KEY_LONG >> 32), (int)(Key_Union.KEY_LONG)); //print the uint64_t, has to be 2 ints to print. 

The output I get is:

{bc9a785634120000} - from the printing of the array

123456789abc - from the printing of the uint64

Where I expected the array printing to be:

{0000123456789abc}

The way I understand unions to work is to overlap the two variables to the same memory space, as such:

(MSB) - - - - - - uint64_t - - - - - - (LSB)

uint8_t[0] .........................uint8_t[8]

but this isn't happening. Any explanation as to why / a solution would be greatly appreciated.

Thanks in advance.

1 Answer

10 years, 9 months ago.

Actually, ARM (at least the Cortex-M core) is a little-endian system. This means that the least significant byte (LSB) of a number is stored at the lowest address ("litte end") which corresponds to the item 0 of the array. So the result is correct.

BTW, to print an int64 in one go, you can use ll format specifier suffix:

pc.printf("\n\r0x%016llx\n\r", Key_Union.KEY_LONG); 

Accepted Answer

That explains it. Thanks!

posted by Henry Lovett 29 Jun 2013