struct alignment mit #pragma pack o.ä.

Gast #640007
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?)
#640022
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
#640096
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!
Gast #640124
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.
Moderator Persönliche Seite #640145
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.
#640929
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren