Was bedeutet "__attribute __ ((gepackt, ausgerichtet (4)))"

122

Es ist C-Sprache. Es steht geschrieben, dass:

typedef struct __attribute__((packed, aligned(4))) Ball {
    float2 delta;
    float2 position;
    //float3 color;
    float size;
    //int arcID;
    //float arcStr;
} Ball_t;
Ball_t *balls;

Bitte sagen Sie mir, was das bedeutet und wie Sie dieses Schlüsselwort verwenden.

Aaron Lee
quelle
4
Es ist ein "Typattribut" . (Ich fand dies mit "C-Attribut gepackt" in Google. Sicherlich können andere mindestens so gut!)
1
Sehen Sie sich diese Frage an - obwohl aligned(4)Sie sich wahrscheinlich nicht viel Sorgen machen müssen.
Keith Thompson

Antworten:

157

Bevor ich antworte, möchte ich Ihnen einige Daten aus dem Wiki geben


Die Datenstrukturausrichtung ist die Art und Weise, wie Daten im Computerspeicher angeordnet und abgerufen werden. Es besteht aus zwei getrennten, aber verwandten Themen: Datenausrichtung und Auffüllen der Datenstruktur .

Wenn ein moderner Computer von einer Speicheradresse liest oder in diese schreibt, geschieht dies in wortgroßen Blöcken (z. B. 4-Byte-Blöcken auf einem 32-Bit-System). Datenausrichtung bedeutet, dass die Daten auf einen Speicherversatz gesetzt werden, der einem Vielfachen der Wortgröße entspricht, was die Systemleistung aufgrund der Art und Weise erhöht, wie die CPU mit Speicher umgeht.

Um die Daten auszurichten, müssen möglicherweise einige bedeutungslose Bytes zwischen dem Ende der letzten Datenstruktur und dem Beginn der nächsten Daten eingefügt werden . Dies ist das Auffüllen der Datenstruktur .


gcc bietet Funktionen zum Deaktivieren des Strukturauffüllens. dh um diese bedeutungslosen Bytes in einigen Fällen zu vermeiden. Betrachten Sie die folgende Struktur:

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}sSampleStruct;

sizeof(sSampleStruct)wird 12 statt 8 sein. Wegen der Strukturauffüllung. In X86 werden Strukturen standardmäßig auf 4-Byte-Ausrichtung aufgefüllt:

typedef struct
{
     char Data1;
     //3-Bytes Added here.
     int Data2;
     unsigned short Data3;
     char Data4;
     //1-byte Added here.

}sSampleStruct;

Wir können verwenden __attribute__((packed, aligned(X))), um auf einer bestimmten (X) Größe Polsterung zu bestehen. X sollte Zweierpotenzen sein. Siehe hier

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}__attribute__((packed, aligned(1))) sSampleStruct;  

Das oben angegebene gcc-Attribut erlaubt daher keine Strukturauffüllung. Die Größe beträgt also 8 Bytes.

Wenn Sie dasselbe für alle Strukturen tun möchten, können wir einfach den Ausrichtungswert zum Stapeln mit verschieben #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)
Jeyaram
quelle
6
Wenn der Speicher Daten in 4-Byte-Blöcken speichert, warum werden dann dem vorzeichenlosen Short (2 Byte lang) keine 2 Auffüllbytes hinzugefügt? oder fügt der Compiler dem ersten und letzten Mitglied der Struktur einfach Füllbytes hinzu? Kannst du es bitte klären?
Benutzer
5
@ Benutzer Plz beziehen sich auch darauf. Wenn Sie immer noch nicht klar sind, kommen Sie bitte um Hilfe stackoverflow.com/questions/11772553/…
Jeyaram
Wer immer gesagt hat, dass diese Füllbytes bedeutungslos sind, weiß nicht, dass ein falsch ausgerichteter Datenzugriff eine Seltsamkeit der x86-Architektur ist. Diese Bytes sind erforderlich, um Ausnahmen zu vermeiden, wenn der Prozessor versucht, beispielsweise eine Ganzzahl zu laden, die sich über die natürliche Ausrichtungsgrenze erstreckt.
Tanveer Badar
86
  • packedbedeutet, dass es den kleinstmöglichen Platz für struct Ball- dh es wird Felder ohne Polsterung zusammenpressen
  • alignedbedeutet, dass jeder struct Ballan einer 4-Byte-Grenze beginnt - dh für jede struct Ballkann seine Adresse durch 4 geteilt werden

Dies sind GCC-Erweiterungen, die nicht Teil eines C-Standards sind.

cnicutar
quelle
17

Das Attribut packedbedeutet, dass der Compiler keine Auffüllung zwischen den Feldern des struct. Das Auffüllen wird normalerweise verwendet, um Felder an ihrer natürlichen Größe auszurichten, da einige Architekturen Strafen für nicht ausgerichteten Zugriff vorsehen oder dies überhaupt nicht zulassen.

aligned(4) bedeutet, dass die Struktur an einer Adresse ausgerichtet werden sollte, die durch 4 teilbar ist.

Julian Stecklina
quelle