Search code examples
c++structendiannessmemory-layout

Does endianness affect the position of struct members in memory?


I'm working with bytes in C++ and was wondering about byte order in memory while taking padding between struct members into consideration, and whether endianness of the system affects the byte order in memory of that struct.

Let's say I have struct:

struct MyStruct {
    unsigned char a;
    int b;
};

Member a takes up 4 bytes (padding was added) and member b also takes up 4 bytes. The question is: Does endianness affect a's byte order in memory or not?

Let's assume that a = 0x01 and b = 0x00000000; will the byte order be:

0x01 0x00 0x00 0x00    0x00 0x00 0x00 0x00

... for both big-endian and little-endian systems, or can it be: or

0x00 0x00 0x00 0x01    0x00 0x00 0x00 0x00

Solution

  • Member a takes up 4 bytes (padding was added) and member b also takes up 4 bytes. The question is: Does endianness affect a's byte order in memory or not?

    Perhaps there's a misunderstanding here. The member a is of type unsigned char, so it always takes up exactly on byte of memory, because sizeof(unsigned char) == 1.

    However, it is possible that the compiler inserts padding bytes between struct members. These padding bytes don't belong to any member, but to the struct itself. This is mostly done to ensure correct alignment of subsequent members. What will likely happen in your example:

    struct MyStruct {
        unsigned char a = 1;
    
        // e.g. three padding bytes inserted between a and b
        char __padding__[alignof(int) - 1];
    
        int b = 0;
    };
    

    No matter how many padding bytes there are, a always appears at the beginning of the struct, so the only legal way to lay out this memory is:

    01 ?? ?? ?? ... ?? 00 00 00 00
    

    It's irrelevant whether the platform endianness is little-endian or big-endian when it comes to the position of members. The endianness only specifies how the bytes inside of an object are laid out. The padding between struct members has nothing to do with that, and is the result of object size and alignment.


    See also: Is a struct's address the same as its first member's address?

    Note: You can use non-standard attributes such as [[gnu::packed]] to eliminate padding bytes between struct members, if really necessary.