2016-05-16 9 views
5

Ich versuche eine Array-Ausrichtung von 8 zur Kompilierzeit zu überprüfen. Dies ist der Code:Überprüfung der C-Array-Ausrichtung zur Kompilierzeit

// File scope 
uint32_t pool[1024]; 
bool aligned = (((uintptr_t) pool) % 8) == 0; 

Ich bekomme diesen Fehler: Initialisierungselement ist nicht berechenbar bei Ladezeit. Wenn ich jedoch die Array-Ausrichtung von 4 überprüfe, erhalte ich den Fehler nicht. Der folgende Code:

// File scope 
uint32_t pool[1024]; 
bool aligned = (((uintptr_t) pool) % 4) == 0; 

Sprache: C

Toolchain: arm-none-EABI-gcc

Compiler-Optionen: -mcpu = Cortex-M3 -mthumb

Warum ist das passiert ?

+0

Warum denken Sie, dass es zur Kompilierzeit gemacht wird? Der Ausdruck, den du geschrieben hast, ist ein Laufzeitausdruck ... was vermisse ich? –

+6

Der Compiler erfordert wahrscheinlich eine 4-Byte-Ausrichtung für "pool" und ist intelligent genug, um zu erkennen, dass die Adresse mod 4 0 ist, unabhängig davon, welche ausgerichtete Adresse verwendet wird. Das selbe kann nicht für die Adresse mod 8 gesagt werden, die vermutlich entweder 0 oder 4 sein wird. –

+0

@TomKarzes danke, dein Kommentar ist, was ich suchte. –

Antwort

3

Die Adresse einer statischen Variablen nicht bekannt ist bei kompilieren Zeit, es wird erst später vom Linker entschieden. Es gibt keine geeignete Verschiebung für "Adresse eines Symbols Modulo irgendeine willkürliche Zahl", die der Compiler als Initialisierungswert für den Linker ausgeben kann, um es zu reparieren, so dass es aufgibt. Wie Tom in den Kommentaren sagt, kann es mindestens davon ausgehen, dass der Linker nicht die minimal erforderliche Ausrichtung für den Typ zu verletzen, ist also in der Lage, den Ausdruck in diesem Fall zu optimieren.

Die einzige Möglichkeit, wie Sie dies erreichen könnten, wäre, es einfach als extern bool aligned zu deklarieren, dann verwenden Sie etwas Linker-Skript schwarze Magie, um es mit dem entsprechenden Wert bei Link-Zeit zu definieren.

5

Wenn Sie eine bestimmte Ausrichtung erzwingen müssen, wird dies berichtet für die „Arm-none-EABI-gcc“ Toolchain arbeiten:

uint32_t pool[1024] __attribute__((aligned(8)));

+0

Dies ist die Antwort auf die Frage, die OP nicht zu fragen scheint. –