[ARM-GCC] Misaligned konstantes Array

OP Persönliche Seite #5661399
Guten Morgen,

ich hab einen Cortex M1 (quasi M0 für FPGAs) und hab da ein seltsames 
Phänomen.

Beispiel in der main.c:
1
const uint8_t txdata[288] = { 0xff, 0xff, 0xff, 0xff, 0x4e, 0x3c, 0xf2, 0x7d, 0x38, 0x38, 0x5a, 0xd5, 0x66, 0xe3, 0x77, usw, };

wird zufällig ausgerichtet. Manchmal an 32Bit, was ich eigentlich 
angenommen hatte, aber oft auch nicht.

Ich hab den Parameter -mno-unaligned-access den Compiler-Schaltern 
hinzugefügt, aber es passiert immer noch.

Sicherlich kann man mit irgendeinem _attribute_ das forcieren, es wäre 
aber schön, wenn der Compiler das gleich richtig machen würde.


Kennt das Problem jemand?

Viele Grüße,
Mampf
Gast
Mampf F. schrieb:
> wäre aber schön, wenn der Compiler das gleich richtig machen würde.

So wie er es macht ist es richtig, so wie vom Standard verlangt. Was du 
als richtig haben möchtest, ist unerheblich...

In C++ kannst du einfach alignas(4) davor schreiben. Für C hat der GCC 
ein Attribut: __attribute__((align(4))) .

Mampf F. schrieb:
> Ich hab den Parameter -mno-unaligned-access den Compiler-Schaltern
> hinzugefügt, aber es passiert immer noch.

Der bewirkt nur Unterschiede bei den Zugriffen, siehe Doku!
OP Persönliche Seite
Dr. Sommer schrieb:
> Mampf F. schrieb:
>> wäre aber schön, wenn der Compiler das gleich richtig machen würde.
>
> So wie er es macht ist es richtig, so wie vom Standard verlangt. Was du
> als richtig haben möchtest, ist unerheblich...

Der Standard kümmert sich wohl nicht um CPU-Architekturen ... Aber sowas 
provoziert doch Fehler ohne Ende - wobei das ist man bei C ja gewöhnt.

Ich nehme an, das kann mir mit lokalen Variablen auf dem Stack oder 
Übergabeparameter nicht passieren?

> In C++ kannst du einfach alignas(4) davor schreiben. Für C hat der GCC
> ein Attribut: __attribute__((align(4))) .

Hatte ich mir gewünscht, der Compiler würde das automatisch machen.

Solange es nur kontante Arrays betrifft, die im Flash/ROM landen ist der 
Aufwand überschaubar.

Bei Daten, die in bss landen wäre es auch blöd ... naja

>
> Mampf F. schrieb:
>> Ich hab den Parameter -mno-unaligned-access den Compiler-Schaltern
>> hinzugefügt, aber es passiert immer noch.
>
> Der bewirkt nur Unterschiede bei den Zugriffen, siehe Doku!

ok, danke^^
Gast
Mampf F. schrieb:
> Aber sowas
> provoziert doch Fehler ohne Ende - wobei das ist man bei C ja gewöhnt.

Wo ist hier ein Fehler? Bei der korrekten Nutzung (also Zugriff ala 
txdata[3]) passiert nichts.

Mampf F. schrieb:
> Ich nehme an, das kann mir mit lokalen Variablen auf dem Stack oder
> Übergabeparameter nicht passieren?
Doch. Die sind nur so weit aligned wie nötig.

Mampf F. schrieb:
> Hatte ich mir gewünscht, der Compiler würde das automatisch machen.

Wozu sollte er unnötig Speicher verschwenden?

Mampf F. schrieb:
> Bei Daten, die in bss landen wäre es auch blöd ... naja
Die betrifft es genauso.

Die Frage ist natürlich: Warum soll das Array 4-Byte aligned sein? Ein 
byte-Array wird auch nur als byte dereferenziert, und bei Bytes ist das 
Alignment bei ARM egal.
OP Persönliche Seite
Dr. Sommer schrieb:
> Mampf F. schrieb:
>> Aber sowas
>> provoziert doch Fehler ohne Ende - wobei das ist man bei C ja gewöhnt.
>
> Wo ist hier ein Fehler? Bei der korrekten Nutzung (also Zugriff ala
> txdata[3]) passiert nichts.

Ok, du hast recht - meine Verwendung von Pointern war falsch.

Der Compiler würde richtig darauf zugreifen, aber wenn ich per 
uint32-Pointer auf ein Byte-Array zugreife, muss ich dann eben aufpassen 
und es explizit alignen.

> Mampf F. schrieb:
>> Ich nehme an, das kann mir mit lokalen Variablen auf dem Stack oder
>> Übergabeparameter nicht passieren?
> Doch. Die sind nur so weit aligned wie nötig.
>
> Mampf F. schrieb:
>> Hatte ich mir gewünscht, der Compiler würde das automatisch machen.
>
> Wozu sollte er unnötig Speicher verschwenden?

Ja, das ist wahr ...
Gast
Mampf F. schrieb:
> Der Compiler würde richtig darauf zugreifen, aber wenn ich per
> uint32-Pointer auf ein Byte-Array zugreife

Ja, das darf man so ohne weiteres natürlich nicht tun... Warum machst du 
das? Nimm doch ein uint32_t Array.
Nimm ein Union aus Byte-Array und Long-Array. Das ist portabler als 
compilerspezifische Attribute und Pragmas und außerdem bildet es auch 
genau das ab was Du anscheinend später mit dem Array sowieso machen 
willst: Mal als byte und mal als long drauf zugreifen. Also nimm im 
Interesse der Lesbarkeit und Verständlichkeit auch die dafür 
vorgesehenen Typdeklarationen und Sprachkonstrukte.

Und bevor jetzt jemand kommt und Vorträge über Type-Punning mit Unions 
hält: Auch bevor seitens des Standardkomitees nachträglich nochmal 
schriftlich klargestellt wurde daß Type-punning mit Unions ab C99 
offiziell erlaubt ist war es schon unstrittig daß ein char-array sowieso 
immer alles aliasen durfte.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.