Why doesn't C++ make the structure tighter?
Asked Answered
K

1

31

For example, I have a class,

class naive {
public:
    char a;
    long long b;
    char c;
    int d;
};

and according to my testing program, a to d are built one after another, like

a-------
bbbbbbbb
c---dddd

- means unused.

Why does not C++ make it tighter, like

ac--dddd
bbbbbbbb
Kittiekittiwake answered 18/7, 2011 at 9:5 Comment(2)
bbbbbbbbddddac would be even tighter and you don't have to pad 2 bytes behindLieutenancy
You have to pad 2 bytes behind anyways in order to satisfy alignment of the whole struct @LieutenancyCaitiff
C
56

Class and struct members are required by the standard to be stored in memory in the same order in which they are declared. So in your example, it wouldn't be possible for d to appear before b.

Also, most architectures prefer that multi-byte types are aligned on 4- or 8-byte boundaries. So all the compiler can do is leave empty padding bytes between the class members.

You can minimize padding by reordering the members yourself, in increasing or decreasing size order. Or your compiler might have a #pragma pack option or something similar, which will seek to minimize padding at the possible expense of performance and code size. Read the docs for your compiler.

Cadent answered 18/7, 2011 at 9:8 Comment(9)
The GCC equivalent of #pragma pack is __attribute__ ((packed)). In C++11 this becomes standardized, with the attribute alignas.Ambassadress
Specifically, the requirement for data members being in the same order in memory is codified in 9.2.12 (Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. [...]) of the ISO/IEC 14882:2003 standard.Mccary
@Martinho, do you have any more information about alignas? I tried to google it but got no clear results. This would be very helpful for me.Colombes
@Killian: You can find it in the latest publicly available standard draft: N3242. Look for section 7.6.2.Ambassadress
What is the reason for not allowing the compiler to rearrange the members in memory?Gley
@Kevin - The C standard says so, because that is the way it worked when C was standardized. Presumably some "clever" code took advantage of this.Vein
@Kevin - A common old-school trick for declaring objects with a header and variable length body is to end the header structure with a dummy array of length one (or length zero if the compiler allows it), and then malloc sizeof(header)+length_of_body. You can then index into the body using the dummy array. If the dummy could be reordered to the beginning of the structure, this wouldn't work.Astigmatic
@Kevin: For the most part, so you can represent RAM areas mapped to hardware registers, network protocols, file formats and similar structures as C structs.Mccary
Can this statement be clarified? "minimize padding at the possible expense of performance and code size". The compiler could take more time but won't lesser padding lead to lesser code size and hence, better run time performance?Albinus

© 2022 - 2024 — McMap. All rights reserved.