www.mikrocontroller.net

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


Autor: Thomas Kindler (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?)

Autor: Axel H. (axelh)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Axel H. (axelh)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.