C++ Speicher-alignment-Frage
Einer Zeile code ist mehr Wert als tausend Worte 🙂 Hier ist mein problem:
/* Platform specific 16-byte alignment macro switch.
On Visual C++ it would substitute __declspec(align(16)).
On GCC it substitutes __attribute__((aligned (16))).
*/
#define ALIGN_16 ...
struct ALIGN_16 A {...};
A* ptr = new A;
A* ptr2 = new A[20];
assert(size_t(ptr) % 16 == 0);
for (int i=0; i<20; ++i)
assert(size_t(ptr2+i) % 16 == 0);
assert(sizeof(A) % 16 == 0);
Kann ich erwarten, dass alle Behauptungen pass auf Plattformen mit SSE-Unterstützung? Danke.
BEARBEITEN. Teilweise Antwort. Ich habe einige test mit VS2008, GCC und ICC. MS-compiler hat so anordnen, ptr und ptr2, aber GCC und ICC-Fehler beim ausrichten ptr2.
- Warum ein array von 20 Als?
- Nur aus meinem Kopf. Ich war Wandern, wenn jedes element des Arrays angeglichen.
- Elemente einer korrekt zugewiesenen Arrays sind garantiert durch die Norm werden korrekt ausgerichtet für die Art in Frage. Allerdings, die Ausrichtung ist eine Implementierung detail und könnte in der Theorie werden zu einem byte (also verpackt Ausrichtung.)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es eine Garantie für die Ausrichtung der Adresse zurück, die von der C++'s neue operation?
In anderen Worten, Sie können den standard zu rechtfertigen Ihre Annahme, dass es funktionieren sollte, aber in der Praxis, es kann die Luft zu sprengen in deinem Gesicht.
Visual C++ 6 nicht richten
doubles
zugeordnet übernew
richtig, so dass Sie gehen.new
odermalloc
, was bedeutet, dass in der Praxis, die behauptet wird scheitern.C++0x bietet ein neues Konstrukt (in [meta.Typ.synop] 20.7.6.6 anderen Transformationen):
die ist garantiert immer korrekt ausgerichtet wurde, soweit ich mich erinnern kann.
Der zweite parameter ist optional und standardmäßig auf die striktesten Anforderungen möglich (so, dass es immer sicher nicht präzise, aber Sie können packen Sie Ihre Typen mehr kompakt, wenn Sie bereit sind zu versuchen).
Abgesehen von bugs, der compiler ist verpflichtet, zu Ehren der Anforderung. Wenn Sie nicht über C++0x, diese finden Sie in der
tr1
namespace oder aufBoost
.Du bist der einzige, die können testen, ob Ihre speziellen compiler keine Ehre dieser Anfrage 🙂
Hinweis: auf
gcc-4.3.2
es ist implementiert als:new
obwohl, die (in der Regel) nicht die spezifischen Ausrichtung Anforderungen. (Normalerweise gibt man 8-byte-aligned-Speicher, der ist gut genug für die meisten Zwecke)new
gibt eine entsprechend ausgerichtete Teil des Speichers (aus 3.7.4.1 [basic.std.dynamisch ist.Zuweisung] $2), es sei denn, ich verstehe nicht, die , so dass es konvertiert werden kann, um einen Zeiger für jede vollständige Objekt-Typ mit einem grundsätzlichen Ausrichtung der Voraussetzung (3.11) und ab 3.11 [basic.align] $2 Eine grundsätzliche Ausrichtung ist vertreten durch eine Ausrichtung weniger als oder gleich der größten Ausrichtung, unterstützt durch die Implementierung in allen Kontexten gleich ist alignof(std::max_align_t) (18.2).new
gibt nur 8-byte-ausgerichtet, Werte undstd::max_align_t
überlegen ist 8, dann die Umsetzung ist nicht konform.