0

For me this piece of code was unexpected. I would previously in my naivity assume that members of a struct that a decleared in order was placed as,

| b1 | b2 | b3 | b4 |
first     second

but I think this snippet show that assumption to be false,

#include <assert.h>
#include <stdint.h>

typedef union {
    struct {
        uint16_t first;
        uint16_t second;
    };
    uint32_t id;
} uuid_t;

int
main(void)
{
    uuid_t uuid;
    uuid.id = 0x11112222;

    assert(uuid.first == 0x1111);
    assert(uuid.second == 0x2222);
}

With the correction,

typedef union {
    struct {
        uint16_t second;
        uint16_t first;
    };
    uint32_t id;
} uuid_t;

asserts will pass and that doesn't yet makes sense to me. Why is that?

Simon
  • 424
  • 4
  • 12
  • 1
    You might want to read about **endianess**. You are running your program on a little endian machine. Besides that you are invoking undefined behaviour as you read a different member of the union than what was written last. – Gerhardh Sep 03 '20 at 09:03
  • 1
    When using type-punning between structure, also beware of [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) – Some programmer dude Sep 03 '20 at 09:07
  • And of course please read about [*endianness*](https://en.wikipedia.org/wiki/Endianness). – Some programmer dude Sep 03 '20 at 09:07
  • Yesyesyes, forgot to include the number 0x11112222 into my universe, began to question reality, then I saw the light. – Simon Sep 03 '20 at 16:42

1 Answers1

2

This seems because little-endian is used in your environment.

In little-endian environment, the number 0x11112222 is stored in memory like

 <--low      high-->
| 22 | 22 | 11 | 11 |

and the structure

struct {
    uint16_t first;
    uint16_t second;
};

probably be

 <--low      high-->
| 22 | 22 | 11 | 11 |
| first   | second  |

Therefore uuid.first will be 0x2222 and uuid.second will be 0x1111 by uuid.id = 0x11112222; in the first code.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70