Is there any environment where “int” would cause struct padding?

后端 未结 5 1183
再見小時候
再見小時候 2021-01-07 18:30

Specifically, this came up in a discussion:

Memory consuption wise, is there a possibility that using a struct of two ints t

相关标签:
5条回答
  • 2021-01-07 18:54

    In your specific example, struct S { int a, b; };, I cannot see any reasonable argument for padding. int should be naturally aligned already, and if it is, int * can and should be the natural representation for pointers, and there is no need for S * to be any different. But in general:

    A few rare systems have pointers with different representations, where e.g. int * is represented as just an integer representing a "word" address, and char * is a combination of a word address and a byte offset into that word (where the byte offset is stored in otherwise unneeded high bits of the word address). Dereferencing a char * happens in software by loading the word, and then masking and shifting to get the right byte.

    On such implementations, it may make sense to ensure all structure types have a minimal alignment, even if it's not necessary for the structure's members, just so that that byte offset mess isn't necessary for pointers to that structure. Meaning it's reasonable that given struct S { char a, b; };, sizeof(S) > 2. Specifically, I'd expect sizeof(S) == sizeof(int).

    I've never personally worked with such implementations, so I don't know if they do indeed produce such padding. But an implementation that does so would be reasonable, and at the very least very close to an existing real-world implementation.

    0 讨论(0)
  • 2021-01-07 18:54

    It would not be totally implausible that a system which can only access memory in 64-bit chunks might have an option to use a 32-bit "int" size for compatibility with other programs that could get tripped up of uint32_t promotes to a larger type. On such a system, a struct with an even number of "int" values would likely not have extra padding, but one with an odd number of values might plausibly do so.

    From a practical perspective, the only way a struct with two int values would need padding would be if the alignment of a struct was more than twice as coarse as that of "int". That would in turn require either that the alignment of structures be coarser than 64 bits, or that the size of int be smaller than 32 bits. The latter situation wouldn't be unusual in and of itself, but combining both in a fashion that would make struct alignment more than twice as coarse as int alignment would seem very weird.

    0 讨论(0)
  • 2021-01-07 18:58

    Is there any reasonable (not necessarily common or current) environment where this small program would print bigger?

    Not that I know of. I know that's not completely reassuring, but I have reason to believe there is no such environment due to the requirements imposed by the C++ standard.

    In a standard-compliant† compiler the following hold:

    • (1) arrays cannot have any padding between elements, due to the way they can be accessed with pointersref;
    • (2) standard layout structs may or may not have padding after each member, but not at the beginning, because they are layout-compatible with "shorter"-but-equal standard layout structsref;
    • (3) array elements and struct members are properly alignedref;

    From (1) and (3), it follows that the alignment of a type is less than or equal to its size. Were it greater, an array would need to add padding to have all its elements aligned. For the same reason, the size of a type is always a whole multiple of its alignment.

    This means that in a struct as the one given, the second member will always be properly aligned—whatever the size and alignment of ints—if placed right after the first member, i.e., no interstitial padding is required. Under this layout, the size of the struct is also already a multiple of its alignment, so no trailing padding is required either.

    There is no standard-compliant set of (size, alignment) values that we can pick that makes this structure need any form of padding.

    Any such padding would then need a different purpose. However, such a purpose seems elusive. Suppose there is an environment that needs this padding for some reason. Whatever the reason for the padding is, it would likely‡ also apply in the case of arrays, but from (1) we know that it cannot.

    But suppose such an environment truly exists and we want a C++ compiler for it. It could support this extra required padding in arrays by simply making ints larger that much, i.e. by putting the padding inside the ints. This would in turn once more allow the struct to be the same size as two ints and leave us without a reason to add padding.


    † A compiler—even one otherwise not-standard-compliant—that gets any of these wrong is arguably buggy, so I'll ignore those.

    ‡ I guess that in an environment where arrays and structures are primitives there might be some underlying distinction that allows us to have unpadded arrays and padded structs, but again, I don't know of any such thing in use.

    0 讨论(0)
  • 2021-01-07 19:03

    I know this is not what you asked for, it's not in the spirit of your question (as you probably have standard layout classes in mind), but strictly answering just this part:

    Memory consuption wise, is there a possibility that using a struct of two ints take more memory than just two ints?

    the answer is kinda... yes:

    struct S
    {
        int a;
        int b;
    
        virtual ~S() = default;
    };
    

    with the pedantic note that C++ doesn't have structs, it has classes. struct is a keyword that introduces the declaration/definition of a class.

    0 讨论(0)
  • 2021-01-07 19:08

    Theoretically padding is used to provide efficient way of accessing memory area.If adding padding to 2 integer variable would increase the efficient than yes it can have padding.But practically I haven't came across any structure with 2 integer have padding bits.

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