Ausrichtung der Struktur in Visual C++
Visual C++ bietet sowohl einen compiler-Schalter (/Zp
) und die pack
pragma Einfluss auf die Ausrichtung in Ordnung struct Mitglieder. Jedoch, mir scheint, ich habe einige Missverständnis, wie Sie arbeiten.
Laut MSDN, für einen gegebenen Werte n,
Die Ausrichtung eines Mitglieds wird auf eine Grenze, die entweder aus einer
Vielfaches von n oder ein Vielfaches von der Größe der Mitgliedstaaten, wobei
kleiner.
Lassen Sie uns annehmen, pack den Wert 8 bytes (das ist die Standardeinstellung). Innerhalb einer struct, würde ich denken, dass jedes Mitglied, dessen Größe weniger als 8 bytes werden bei einem offset, der ein Vielfaches seiner eigenen Größe. Jedes Mitglied, dessen Größe von 8 bytes oder mehr wird ein offset, der ein Vielfaches von 8 bytes.
Nehmen Sie nun das folgende Programm:
#include <tchar.h>
#pragma pack(8)
struct Foo {
int i1;
int i2;
char c;
};
struct Bar {
char c;
Foo foo;
};
int _tmain(int argc, _TCHAR* argv[]) {
int fooSize = sizeof(Foo); //yields 12
Bar bar;
int fooOffset = ((int) &bar.foo) - ((int) &bar); //yields 4
return 0;
}
Den Foo
Struktur ist 12 Byte groß sind. Also innerhalb Bar
, würde ich erwarten, dass die Foo
Mitglied werden bei offset 8 (Vielfaches von 8), während tatsächlich es ist an offset 4. Warum ist das so?
Auch Foo
wirklich nur 4+4+1 = 9 bytes of data. Der compiler fügt automatisch padding bytes am Ende. Aber wieder, angesichts ein alignment-Wert von 8 bytes ist, sollte es nicht pad wird ein Vielfaches von 8 statt 4?
Jede Klärung dankbar!
- Sind Sie sicher, dass Ihre
int
ist nur 4 bytes? In welcher Maschine Sie diese auf? - Es ist eine 32 bit-Anwendung. Wenn ein int mit 8 Byte statt 4, ein Foo mit zwei von denen konnte nicht gut sein, nur 12 Byte. 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihren Auszug erklärt, "je nachdem was kleiner ist". Auf einem 32-bit-Plattform, eine
int
ist 4 bytes. 4 ist kleiner als 8. So hat es eine 4-byte-Ausrichtung.Den
pack
pragma bewirkt, dass Dinge verpackt werden, nicht ausgepackt. Es wird nicht das pad, es sei denn, es hat einen Grund.Foo
ist 4. Es ist nicht der größte Typ, aber die Voraussetzung für die äußere Struktur, die in der Regel werden die größten alignment-Anforderung alle enthaltenen Typ, aber nicht immer. (Es kann nicht sein, die Größe des vollständigen Typs. Ansonsten, eine ganze Zahl, gefolgt von einem 9.000 byte-Struktur hätte fast 9.000 bytes Polsterung. Das ist einfach nur albern. Auf der MSDN-Seite ist das reden über einfache Typen, deren Angleichung Voraussetzung ist gleich Ihrer Größe.)Halten Sie im Verstand, warum die Ausrichtung Angelegenheiten, die in den ersten Platz. Es ist es zu ermöglichen, die cpu-lese-Speicher schnell die zimmerreserviereung, ohne das multiplex-bytes. Die cpu-nevers Lesen eine Struktur, in einem Zug, es greift nur auf seine Mitglieder. Also die Tatsache, dass die Foo struct ist 12 bytes, ist dabei unerheblich. Nur die Ausrichtung seiner Mitglieder zählt. Noch kein Foo-Mitglied hat ein alignment-Anforderung größer als 4, die Bar.foo-Mitglied muss nur in der Angleichung an die 4.
Foo 12 bytes statt 9 könnte eine Erklärung gut. Fügt der compiler 3 bytes der Polsterung an das Ende, so dass ein array von Foo hat noch die Mitglieder korrekt ausgerichtet für jedes array-element.
Als dein Zitat sagt - zum testen ein 8-byte alignment braucht man 8 oder mehr-byte-Datentypen. Hier ist ein Beispiel mit einigen expliziten mittelgroßen Arten. Auch setzen die kleine element am Ende nicht zeigen, ist die Polsterung wie es sein kann, ging von dem Ende der Struktur.
Erstellung dieses mit VC 2010: