Betrachten Sie dieses einfache ProgrammWarum funktioniert dieser Strukturfülltrick?
#include <iostream>
struct A
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
int main()
{
std::cout << sizeof(A) << ' ' << sizeof(B) << '\n';
return 0;
}
Diese 8 12
druckt. Auch wenn B
in 8 Bytes gepackt werden kann, ohne die Ausrichtungsanforderungen zu brechen, nimmt es statt dessen gierige 12 Bytes auf.
Es wäre schön, sizeof(B) == 8
zu haben, aber die Antwort auf Is the size of a struct required to be an exact multiple of the alignment of that struct? schlägt vor, dass es keinen Weg gibt.
war ich daher überrascht, als der
struct MakePackable
{
};
struct A : MakePackable
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
gedruckt 8 8
folgende.
Was geht hier vor? Ich vermute, dass Standard-Layout-Typen etwas damit zu tun haben. Wenn ja, was ist der Grund dafür, dass das obige Verhalten verursacht wird, wenn der einzige Zweck dieses Features darin besteht, die Binärkompatibilität mit C zu gewährleisten?
EDIT: Wie andere haben darauf hingewiesen, dies ist ABI oder Compiler spezifisch, so dass ich sollte hinzufügen, dass dieses Verhalten auf x86_64-unknown-linux-gnu mit den folgenden Compiler beobachtet wurde:
- 3.6 Klirren
- gcc 5,1
ich habe auch bemerkt etwas seltsam aus Klirren der struct dumper. Wenn wir für die Datengröße ohne Schwanz padding („dsize“) fragen,
A B
first 8 9
second 7 8
dann im ersten Beispiel erhalten wir dsize(A) == 8
. Warum ist das nicht 7?
Vielleicht gibt es keine anderen Gründe als Compiler-Implementierungsdetails ... – deviantfan
Sie werden nach einem bestimmten ABI fragen müssen, da es fast keine Chance gibt, dass dieses Verhalten im Rahmen von C++ selbst liegt. FWIW, ich kann in Itanium (auf einen kurzen Blick) nichts finden, um dies zu erklären, obwohl ich '8 8' mit GCC 5.1 bekomme, also ...:/ –
Passt das Tag [tag: sprachanwalt] für diese Frage? –