3

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
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Feralnex
  • 61
  • 5
  • 2
    endianness defines how you interpret the memory, not the size of the memory that will be used. – NathanOliver Jun 20 '23 at 19:47
  • 3
    "Member "a" takes 4 bytes (padding was added) " no. `a` takes `sizeof(unsigned char)` and after that there is maybe padding. – 463035818_is_not_an_ai Jun 20 '23 at 19:48
  • 3
    very related, maybe duplicate: https://stackoverflow.com/q/9254605/4117728. Padding is never added in front. `a` is always stored in the first byte – 463035818_is_not_an_ai Jun 20 '23 at 19:51
  • @463035818_is_not_an_ai so bytes representing a value saved in a specific endianness will always start at the address of the member and it's length will be the size of the type of the member and after that (maybe) will be an added padding which isn't taken into consideration when saving bytes of the member based on the endianness of the system? If "a" would be of type short (2 bytes) then the byte order would be 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 or 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 is that correct? – Feralnex Jun 20 '23 at 20:16
  • 1
    @Feralnex - There is no byte order for a single byte element. How could there be? – BoP Jun 20 '23 at 21:14
  • The ordering of members of an ordinary struct or class will probably be unaffected. The order of members of members that are bitfields may be affected. – Peter Jun 21 '23 at 01:18

2 Answers2

3

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.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
  • So if I get offset of the member of the struct and also it's size then I can always assume that starting from that offset with that size are the bytes of specific member and padding doesn't impact anything when it comes to that bytes of that member and padding comes always after specific member if needed? – Feralnex Jun 21 '23 at 17:51
  • 1
    @Feralnex if you mean `offsetof` then yes, it always gives you the position of the first byte of a struct member, and then the next `sizeof(member)` bytes are occupied by that member. There might be padding after it. – Jan Schultke Jun 21 '23 at 18:59
1

Does endianness affect "a" byte order in memory or not?

a is a single byte object. It's layout is unaffected by endianness.

Endianness also doesn't affect order of struct members in memory.

will byte order be 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 for both big endian and little endian system?

In this case the first byte is guaranteed to be the byte of a. If your assumptions about padding and size of the types matches the implementation details, then the answer is yes, in this case.

eerorika
  • 232,697
  • 12
  • 197
  • 326