Is the size of a struct required to be an exact multiple of the alignment of that struct?

前端 未结 9 2064
萌比男神i
萌比男神i 2020-11-28 13:00

Once again, I\'m questioning a longstanding belief.

Until today, I believed that the alignment of the following struct would normally be 4 and the size would normall

相关标签:
9条回答
  • 2020-11-28 13:21

    5.3.3/2

    When applied to a class, the result [of sizeof] is the number of bytes in an object of that class, including any padding required for placing objects of that type in an array.

    So yes, object size is a multiple of its alignment.

    0 讨论(0)
  • 2020-11-28 13:28

    Seems the C++03 standard didn't say (or I didn't find) whether the alignment padding bytes should be included in the object representation.

    And the C99 standard says the "sizeof" a struct type or union type includes internal and trailing padding, but I'm not sure if all alignment padding is included in that "trailing padding".

    Now back to your example. There is really no confusion. sizeof(example) == 8 means the structure does take 8 bytes to represent itself, including the tailing 3 padding bytes. If the char in the second structure has an offset of 6, it will overwrite the space used by m_Example. The layout of a certain type is implementation-defined, and should be kept stable in the whole implementation.

    Still, whether p+1 equals (T*)((char*)p + sizeof(T)) is unsure. And I'm hoping to find the answer.

    0 讨论(0)
  • 2020-11-28 13:35

    I am unsure if this is in the actual C/C++ standard, and I am inclined to say that it is up to the compiler (just to be on the safe side). However, I had a "fun" time figuring that out a few months ago, where I had to send dynamically generated C structs as byte arrays across a network as part of a protocol, to communicate with a chip. The alignment and size of all the structs had to be consistent with the structs in the code running on the chip, which was compiled with a variant of GCC for the MIPS architecture. I'll attempt to give the algorithm, and it should apply to all variants of gcc (and hopefully most other compilers).

    All base types, like char, short and int align to their size, and they align to the next available position, regardless of the alignment of the parent. And to answer the original question, yes the total size is a multiple of the alignment.

    // size 8
    struct {
        char A; //byte 0
        char B; //byte 1
        int C; //byte 4
    };
    

    Even though the alignment of the struct is 4 bytes, the chars are still packed as close as possible.

    The alignment of a struct is equal to the largest alignment of its members.

    Example:

    //size 4, but alignment is 2!
    struct foo {
        char A; //byte 0
        char B; //byte 1
        short C; //byte 3
    }
    
    //size 6
    struct bar {
        char A;         //byte 0
        struct foo B;   //byte 2
    }
    

    This also applies to unions, and in a curious way. The size of a union can be larger than any of the sizes of its members, simply due to alignment:

    //size 3, alignment 1
    struct foo {
        char A; //byte 0
        char B; //byte 1
        char C; //byte 2
    };
    
    //size 2, alignment 2
    struct bar {
        short A; //byte 0
    };
    
    //size 4! alignment 2
    union foobar {
        struct foo A;
        struct bar B;
    }
    

    Using these simple rules, you should be able to figure out the alignment/size of any horribly nested union/struct you come across. This is all from memory, so if I have missed a corner case that can't be decided from these rules please let me know!

    0 讨论(0)
提交回复
热议问题