[ARM-GCC] Misaligned konstantes Array

Persönliche Seite #5661399
Lesenswert?

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 #5661410
Lesenswert?

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!
Persönliche Seite #5661417
Lesenswert?

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 #5661427
Lesenswert?

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.
Persönliche Seite #5661517
Lesenswert?

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 ...
#5661539
Lesenswert?

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

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