Is struct packing deterministic?

后端 未结 8 2051
北荒
北荒 2020-12-13 18:00

For example, say I have two equivalent structs a and b in different projects:

typedef struct _a
{
    int a;
    double b;
    char         


        
相关标签:
8条回答
  • 2020-12-13 18:24

    You cannot approach deterministically the layout of a structure or union in C language on different systems.

    While many times it could seem that the layout generated by different compilers is the same, you must consider the cases a convergence dictated by practical and functional convenience of compiler design in the ambit of choice freedom left to the programmer by the standard, and thus not effective.

    The C11 standard ISO/IEC 9899:2011, almost unchanged from previous standards, clearly stated in paragraph 6.7.2.1 Structure and union specifiers:

    Each non-bit-field member of a structure or union object is aligned in an implementation defined manner appropriate to its type.

    Even worst the case of bitfields where a large autonomy is left to the programmer:

    An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

    Just count how many times the terms 'implementation-defined' and 'unspecified' appear in the text.

    Agreed that to check compiler version, machine and target architecture each run before to use structure or union generated on a different system is unaffordable you should have got a decent answer to your question.

    Now let's say that yes, there is a way-around.

    Be clear that it is not definitely the solution, but is a common approach that you can found around when data structures exchange is shared between different systems: pack structure elements on value 1 (standard char size).

    The use of packing and an accurate structure definition can lead to a sufficiently reliable declaration that can be used on different systems. The packing forces the compiler to remove implementation defined alignments, reducing the eventual incompatibilities due to standard. Moreover avoiding to use bitfields you can remove residual implementation dependent inconsistencies. Last, the access efficiency, due to missing alignment can be recreated by manually adding some dummy declaration inbetween elements, crafted in such a way to force back each field on correct alignment.

    As a residual case you have to consider a padding at structure end that some compilers add, but because there is no useful data associated you can ignore it (unless for dynamic space allocation, but again you can deal with it).

    0 讨论(0)
  • 2020-12-13 18:28

    will they have identical padding between variables?

    In practice, they mostly like to have the same memory layout.

    In theory, since the standard doesn't say much on how padding should be employed on objects, you can't really assume anything on the padding between the elements.

    Also, I can't see even why would you want to know/assume something about the padding between the members of a struct. simply write standard, compliant C code and you'll be fine.

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