Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any environment where "int" would cause struct padding?

Specifically, this came up in a discussion:

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

Or, in language terms:

#include <iostream>

struct S { int a, b; };

int main() {
    std::cout << (sizeof(S) > sizeof(int) * 2 ? "bigger" : "the same") << std::endl;
}

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

1To clarify, what I meant here is systems (and compilers) developed and produced in some meaningful quantity, and specifically not theoretical examples constructed just to prove the point, or one-off prototypes or hobbyist creations.

like image 729
Bartek Banachewicz Avatar asked Sep 04 '17 12:09

Bartek Banachewicz


People also ask

Why does structure padding happen?

The structure padding is automatically done by the compiler to make sure all its members are byte aligned. Here 'char' is only 1 byte but after 3 byte padding, the number starts at 4 byte boundary. For 'int' and 'double', it takes up 4 and 8 bytes respectively.

How can we prevent padding in structure?

In Structure, sometimes the size of the structure is more than the size of all structures members because of structure padding. Note: But what actual size of all structure member is 13 Bytes. So here total 3 bytes are wasted. So, to avoid structure padding we can use pragma pack as well as an attribute.

Why do struct types in C sometimes contain padding?

The variable 'c' is of 4 bytes, so it can be accessed in one cycle also, but in this scenario, it is utilizing 2 cycles. This is an unnecessary wastage of CPU cycles. Due to this reason, the structure padding concept was introduced to save the number of CPU cycles.

Why does the compiler sometimes insert padding between fields?

The compiler will insert a padding byte after the char to ensure short int will have an address multiple of 2 (i.e. 2 byte aligned).


1 Answers

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&ddagger; 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.

&ddagger; 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.

like image 147
R. Martinho Fernandes Avatar answered Oct 16 '22 16:10

R. Martinho Fernandes