Forum: Compiler & IDEs struct alignment mit #pragma pack o.ä.


von Thomas Kindler (Gast)


Lesenswert?

Hallo!

Ich bin gerade dabei, mir eine Datenstruktur zu basteln, und hätte gerne 
ein 2-byte-aligment für die einzelnen Elemente, d.h.:

  struct foo {
    uint16_t  a;
    uint8_t   b;
    uint8_t   c;
    uint8_t   d;
    uint16_t  e;
  };

  offsetof(foo, a) == 0;
  offsetof(foo, b) == 2;
  offsetof(foo, c) == 3;
  offsetof(foo, d) == 4;
  offsetof(foo, e) == 6;  (anstatt 5 ohne aligment).

Unter normalen umständen würde man die Definition in ein

  #pragma pack(push,2)
  ..
  #pragma pack(pop)

verpacken, der avr-gcc meldet jedoch:

  warning: ignoring #pragma pack

Ein nachgestelltes "__attribute__ ((aligned (2)))" funktioniert auch 
nicht:

  warning: alignment of 'foo' is greater than maximum object file 
alignment.  Using 1

Gibt's noch andere Möglichkeiten (abgesehen von manuell eingefügtem 
padding?)

von Axel H. (axelh)


Lesenswert?

> Gibt's noch andere Möglichkeiten (abgesehen von manuell eingefügtem
> padding?)

Ich würde dazu raten, manuelles Padding zu benutzen und Dummy-Felder 
einzufügen. Dann ist aus dem Quellcode klar, was gemeint ist. Ansonsten 
kann es manchmal merkwürdige Effekte geben, wenn man den Compiler oder 
die Architektur wechselt und das mit dem Alignment nicht mehr klappt.

Axel

von Uhu U. (uhu)


Lesenswert?

Zu manuellem Padding würde ich nicht raten - das gibt nur eine Quelle 
schwer zu findender Fehler, wenn das Programm nachträglich verändert 
wird und dann auf das Alignment aus den Augen geraten ist. Ich spreche 
aus Erfahrung...

Das #pragma pack(push,2) ist Microsoft Visual C - kann das der gcc 
überhaupt? (Pragmas sind nicht standardisiert!)

Lies mal im Manual nach!

von Rolf Magnus (Gast)


Lesenswert?

> Unter normalen umständen würde man die Definition in ein
>
>  #pragma pack(push,2)
>  ..
>  #pragma pack(pop)

Was verstehst du unter "normalen umständen"?

>   warning: alignment of 'foo' is greater than maximum object file
> alignment.  Using 1

Anscheinend arbeitest du mit einer Zielplattform, die keine speziellen 
Alignment-Anforderungen hat.

> Gibt's noch andere Möglichkeiten (abgesehen von manuell eingefügtem
> padding?)

Warum kein manuelles Padding?

> Zu manuellem Padding würde ich nicht raten - das gibt nur eine Quelle
> schwer zu findender Fehler, wenn das Programm nachträglich verändert
> wird und dann auf das Alignment aus den Augen geraten ist.

Die gibt es bei jeder Änderung der Struktur, wenn diese zur 
Kommunikation zwischen verschiedenen Systemen verwendet wird.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas Kindler wrote:

> Ein nachgestelltes "__attribute__ ((aligned (2)))" funktioniert auch
> nicht:
>
>   warning: alignment of 'foo' is greater than maximum object file alignment. 
Using 1

GCC ist nur gewillt, auf kleinere Grenzen auszurichten, als es die
Zielplattform erfordert, du willst aber offenbar auf eine größere
Grenze ausrichten.

Ich stimme denjenigen hier zu, dass du die Sache nur portabel lösen
kannst, indem du alles manuell ausrichtest.

von Axel H. (axelh)


Lesenswert?

> Zu manuellem Padding würde ich nicht raten - das gibt nur eine Quelle
> schwer zu findender Fehler, wenn das Programm nachträglich verändert
> wird und dann auf das Alignment aus den Augen geraten ist. Ich spreche
> aus Erfahrung...

Ich auch :)
Ich tendiere halt eher zum manuellen Padding und zusätzlilich noch zu 
einem dicken fetten Kommentar überall da, wo das Padding wirklich 
wichtig und beabsichtigt ist. Und dann am besten noch viele assert() in 
eine Init-Routine, die alle fliegen, wenn was nicht passt. Und trotzdem 
wird es bei jeder neuen Portieren halt doch Überraschungen geben. Ist 
halt auch sowas, was im C-Standard irgendwie nicht wirklich drinnen ist.

Axel

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.