Frage

Ich habe den folgenden Code:

#include <stdio.h>

int
main(void)
{
        float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
        printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}

Und ich habe die folgende Ausgabe:

0x7fffbfcd2da0 0x7fffbfcd2da4 0x7fffbfcd2da8 0x7fffbfcd2dac

Warum die Adresse a[0] nicht ein Vielfaches von 0x1000 ist?

Was genau __attribute__((aligned(x))) tut? Ich falsch verstanden dieser Erklärung?

Ich bin mit gcc 4.1.2.

War es hilfreich?

Lösung

Ich glaube, das Problem ist, dass Ihr Array auf dem Stapel ist. Da der Stapelzeiger alles sein könnte, wenn die Funktion gestartet wird, gibt es keine Möglichkeit, die Anordnung auszurichten, ohne viel mehr zu Zuweisung als Sie brauchen, und passt ihn. Wenn Sie das Array aus der Funktion und in einer globalen Variablen zu verschieben, sollte es funktionieren. Die andere Sache, die Sie tun können, ist es zu halten, wie eine lokale Variable (das ist eine sehr gute Sache ist), aber es static. Dies wird verhindern, dass es auf dem Stapel gespeichert werden. Beachten Sie, dass diese beiden Wege sind nicht Thread-sicher oder Rekursion sicher, da es nur eine Kopie des Arrays sein.

Mit diesem Code:

#include <stdio.h>

float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};

int
main(void)
{
        printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}

Ich bekomme diese:

0x804c000 0x804c004 0x804c008 0x804c00c

Das ist, was erwartet wird. Mit Ihrem ursprünglichen Code, erhalte ich nur zufällige Werte wie Sie haben.

Andere Tipps

Es war in gcc ein Fehler, der verursacht Attribut ausgerichtet ist, nicht mit Stack-Variablen zu arbeiten. Es scheint mit dem Patch unter unten stehenden Link fixiert werden. Der Link unten enthält auch einiges an Diskussion für das Problem auch.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660

Ich habe den Code versucht, oben mit zwei verschiedenen Versionen von gcc 4.1.2 von einem RedHat 5.7 Box, und es scheiterte in ähnlicher Weise für Ihr Problem (die lokalen Arrays wre in keiner Weise auf 0x1000 Byte boundaies ausgerichtet). Ich habe dann versucht, Ihren Code mit gcc 4.4.6 auf RedHat 6,3, und es funktionierte einwandfrei (die lokalen Arrays wurden aligned). Die Myth TV Leute hatten ein ähnliches Problem (das der gcc-Patch über zu beheben schien):

http://code.mythtv.org/trac/ticket/6535

Wie auch immer, es sieht aus wie Sie einen Fehler in gcc gefunden, die in späteren Versionen behoben zu sein scheint.

Neue GCC (mit 4.5.2-8ubuntu4 getestet) erscheint als mit dem Array richtig ausgerichtet erwartet funktionieren.

#include <stdio.h>

int main(void)
{
    float a[4] = { 1.0, 2.0, 3.0, 4.0 };
    float b[4] __attribute__((aligned(0x1000))) = { 1.0, 2.0, 3.0, 4.0 };
    float c[4] __attribute__((aligned(0x10000))) = { 1.0, 2.0, 3.0, 4.0 };

    printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
    printf("%p %p %p %p\n", &b[0], &b[1], &b[2], &b[3]);
    printf("%p %p %p %p\n", &c[0], &c[1], &c[2], &c[3]);
}

ich:

0x7ffffffefff0 0x7ffffffefff4 0x7ffffffefff8 0x7ffffffefffc
0x7ffffffef000 0x7ffffffef004 0x7ffffffef008 0x7ffffffef00c
0x7ffffffe0000 0x7ffffffe0004 0x7ffffffe0008 0x7ffffffe000c

Alignement ist für alle Arten nicht wirksam. Sie sollten erwägen, eine Struktur mit den Attributen in Aktion zu sehen:

#include <stdio.h>

struct my_float {
        float number;
}  __attribute__((aligned(0x1000)));

struct my_float a[4] = { {1.0}, {2.0}, {3.0}, {4.0} };

int
main(void)
{
        printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}

Und dann werden Sie lesen:

0x603000 0x604000 0x605000 0x606000

Das ist, was Sie erwartet haben.

Edit: Gedrückt von @yzap und folgenden @Caleb Fall Kommentar, das ursprüngliche Problem ist aufgrund der GCC-Version nur . Ich habe auf GCC 3.4.6 vs GCC 4.4.1 mit dem Anforderer Quellcode geprüft:

$ ./test_orig-3.4.6
0x7fffe217d200 0x7fffe217d204 0x7fffe217d208 0x7fffe217d20c
$ ./test_orig-4.4.1
0x7fff81db9000 0x7fff81db9004 0x7fff81db9008 0x7fff81db900c

Es ist nun offensichtlich, dass ältere GCC-Versionen (irgendwo vor 4.4.1) zeigen die Ausrichtung Pathologien.

Anmerkung 1: Mein Vorschlag Code nicht die Frage beantworten, die ich als „jedes Feld Ausrichten des Arrays“ verstanden

.

Hinweis 2: Bringing nicht-statisch a [] innerhalb main () und mit GCC 3.4.6 brechen die Ausrichtung Richtlinie des Arrays von struct Kompilieren aber hält 0x1000 Abstand zwischen structs ... immer noch schlecht! (Siehe @zifre Antwort für Abhilfen)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top