0

I have a situation with two structures that are combined as members of a larger structure. The first one is 44 bytes, and the second one is 1047. The second structure ends with a char. Excerpt:

typedef struct
{
    ... (total of 44 bytes, all members naturally aligned)
} StructA;

typedef struct
{
    ...lots of stuff totaling 1046 bytes
    char flag;
} StructB;

typedef struct
{
    StructA a;
    StructB b;
} StructC;

Printing sizeof of StructA and StructB produces the expected sizes of 44 and 1047 respectively. Printing sizeof StructC produces 1092, which is 44 + 1047 + 1. It seems pretty clear to me that the compiler is padding the overall structure because of the single byte at the end of StructB. But it's at the end...there are no following members that require alignment. So why is it padding StructC? And why does it not pad StructB the same way?

This is built with Microsoft Visual Studio 2013; we're also cross-platform, but I don't yet know if GNU compiler on Linux treats this the same or not. If it doesn't, that will also be a concern.

Thank you, Doug

Follow up:

My question was marked as a duplicate but the referral doesn't answer the specific issue I'm trying to address, which is specifically why padding was added at the end of the structure in one circumstance, but not in the other.

goug
  • 2,294
  • 1
  • 11
  • 15
  • If StructA requires some alignment, than StructC also will require the same alignment. Otherwise `(new StructC[2])[1].a` would be misaligned. – zch Apr 14 '15 at 19:19
  • Since `StructA` is 44 bytes, `StructB` is 4 byte aligned when in `StructC`. I can't explain the padding at the end. My only guess would be to allow the next variable to be also 4 byte aligned. – Jonas Wolf Apr 14 '15 at 19:26
  • 2
    Extra padding is added to ensure the structure members are *still* aligned when you store them in an array. You can only get 44 bytes if none of the structure members are larger than 4 bytes so the probable alignment requirement for StructA is 4. 1091 is a very unhappy number, 1 extra byte is needed to ensure the StructC.a member aligns to 4 again when you store StructC in an array. – Hans Passant Apr 14 '15 at 19:32
  • The compiler will add the padding bytes depending on how you use the structures. If in your code you use only StructC, it makes sense padding only StructC. That's why StructB is not padded to divide by 4. – VAndrei Apr 14 '15 at 19:36
  • If you need the structures to be padded (or not padded) for a specific reason, no matter if the compiler naturally aligns them the way you want or not, you should use `#pragma pack` to ensure it is the way you expect it to be. – RyanP Apr 14 '15 at 19:53
  • Hans, my immediate reaction was that you were correct, and I hadn't thought of that, but there's still a discrepancy. You're correct that StructA has 4-byte members and requires 4-byte alignment, but that's also true of StructB. So if the padding is to ensure alignment when used in an array, why is StructB not padded under both circumstances? When it stands on its own, it isn't padded, but when included as the final member of the other structure, it is. – goug Apr 14 '15 at 22:26
  • I figured it out, and Hans is completely correct. The StructB definition--not one of mine--has a "#pragma pack (push, 1)" on it (which I hadn't noted in my question). It shouldn't, but it does, and I've lost that argument so far. So...when StructB is used on its own, even in an array, alignment requirements have been nullified. StructA does NOT have the pack pragma and requires 4-byte alignment, so when I use them together, the combined result must be padded in order for each element in an array to be properly aligned. Thank you, Hans, for getting me on the right track. – goug Apr 14 '15 at 22:34

0 Answers0