Warum ist das Ausrichten von langen long union member größer als die beinhaltende union / struct? Ist das richtig?

8

Aus dieser Frage könnte man anfangen zu glauben, dass die Ausrichtung einer Gewerkschaft dies nicht ist weniger als die größte Ausrichtung seiner einzelnen Mitglieder. Aber ich habe ein Problem mit dem long long -Typ in gcc / g ++. Das vollständige Beispiel finden Sie hier , aber hier sind die relevanten Teile für meine Frage:

%Vor%

Dies ergibt die folgende Ausgabe:

%Vor%

Warum ist die Ausrichtung eines Union-Elements größer als die der enthaltenen Union?

[UPDATE]

Nach Keiths Antwort ist alignof hier falsch. Aber ich teste das Folgende und es scheint, dass alignof uns das Wahre sagt. Siehe:

%Vor%

Die Ausgabe:

%Vor%

Die Ausrichtung von long long ist also 8 und die Ausrichtung der Union mit long long ist 4 in globalen Daten. Für den lokalen Bereich kann ich das nicht testen, da es dem Compiler freisteht, lokale Daten neu anzuordnen - dieser Trick funktioniert also nicht. Können Sie das kommentieren?

[/ UPDATE]

    
PiotrNycz 06.08.2012, 08:48
quelle

1 Antwort

7

__alignof__ (was eine gcc-Erweiterung ist) gibt nicht unbedingt die erforderliche -Ausrichtung für einen Typ an.

x86-Prozessoren erfordern beispielsweise nicht wirklich mehr als 1-Byte-Ausrichtung für jeden Typ. Der Zugriff auf ein 4-Byte- oder 8-Byte-Objekt ist wahrscheinlich effizienter, wenn das Objekt wortausgerichtet ist, aber die Byte-Ausrichtung ist ausreichend.

Zitieren Sie die gcc-Dokumentation :

  

Einige Maschinen erfordern niemals eine Ausrichtung; sie erlauben Referenz   zu irgendeinem Datentyp sogar an einer ungeraden Adresse. Für diese Maschinen    __alignof__ gibt die kleinste Ausrichtung an, die GCC angibt   Datentyp, normalerweise wie von der Ziel-ABI vorgeschrieben.

Aber das beantwortet die Frage immer noch nicht wirklich. Selbst mit dieser losen Definition kann ich keinen guten Grund für __alignof__ finden, eine striktere Ausrichtung für long long anzuzeigen als für eine Struktur oder eine Union, die ein long long enthält.

Eine portablere Methode zum Bestimmen der Ausrichtung eines Typs ist dies:

%Vor%

Dies ergibt den Offset eines Elements vom Typ t in einer Struktur, die aus einem char und einem t besteht. Verwenden Sie dieses Makro, dieses Programm:

%Vor%

erzeugt diese Ausgabe auf meinem System (gcc-4.7, Ubuntu 12.04, x86):

%Vor%

Die Ergebnisse, die von meinem Makro ALIGNOF() angezeigt werden, sind konsistent: long long hat eine 4-Byte-Ausrichtung, und eine Struktur oder Union mit einem long long hat eine 4-Byte-Ausrichtung.

Ich vermute, dass dies ein Fehler oder zumindest eine Inkonsistenz in der GCC-Implementierung von __alignof__ ist. Aber die Unbestimmtheit der Definition macht es schwer, sicher zu sein, dass es wirklich ein Fehler ist. Es wurde anscheinend nicht berichtet .

Aktualisierung:

Ich könnte die Waffe springen lassen, aber ich habe gerade einen Fehlerbericht eingereicht.

Dieser frühere Fehlerbericht , der als "INVALID" geschlossen wurde, ist ähnlich, tut es aber nicht beziehen Sie sich nicht auf die Ausrichtung der Struktur selbst.

Update 2:

Mein Fehlerbericht wurde als Duplikat des früheren geschlossen. Ich werde um Klärung bitten.

    
Keith Thompson 06.08.2012, 09:10
quelle