C++
Ausrichtung
Suche…
Einführung
Alle Typen in C ++ haben eine Ausrichtung. Dies ist eine Einschränkung für die Speicheradresse, in der Objekte dieses Typs erstellt werden können. Eine Speicheradresse gilt für die Erstellung eines Objekts, wenn das Teilen dieser Adresse durch die Ausrichtung des Objekts eine ganze Zahl ist.
Typenanpassungen sind immer eine Zweierpotenz (einschließlich 1).
Bemerkungen
Der Standard garantiert Folgendes:
- Die Ausrichtungsanforderung eines Typs ist ein Teiler seiner Größe. Eine Klasse mit einer Größe von 16 Byte könnte beispielsweise eine Ausrichtung von 1, 2, 4, 8 oder 16 haben, aber nicht 32. (Wenn die Mitglieder einer Klasse nur 14 Byte groß sind, muss die Klasse jedoch eine Ausrichtungsanforderung haben von 8 fügt der Compiler 2 Padding-Bytes ein, um die Klassengröße auf 16 zu setzen.)
- Die vorzeichenbehafteten und vorzeichenlosen Versionen eines Ganzzahltyps haben dieselbe Ausrichtungsanforderung.
- Ein Zeiger auf
void
hat dieselbe Ausrichtungsanforderung wie ein Zeiger aufchar
. - Die cv-qualifizierten und die cv-nicht qualifizierten Versionen eines Typs haben dieselbe Ausrichtungsanforderung.
Beachten Sie, dass die Ausrichtung zwar in C ++ 03 vorhanden ist, jedoch erst ab C ++ 11 die Möglichkeit bestand, die Ausrichtung (mithilfe von alignof
) und die Ausrichtung der Ausrichtung (mithilfe von alignas
) alignas
.
Die Ausrichtung eines Typs abfragen
Die Ausrichtungsanforderung eines Typs kann mit dem Schlüsselwort alignof
als unären Operator abgefragt werden. Das Ergebnis ist ein konstanter Ausdruck vom Typ std::size_t
, dh er kann zur Kompilierzeit ausgewertet werden.
#include <iostream>
int main() {
std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}
Mögliche Ausgabe
Die Ausrichtungsanforderung von int ist: 4
Bei Anwendung auf ein Array ergibt sich die Ausrichtungsanforderung des Elementtyps. Bei Anwendung auf einen Referenztyp ergibt sich die Ausrichtungsanforderung des referenzierten Typs. (Verweise selbst haben keine Ausrichtung, da sie keine Objekte sind.)
Ausrichtung kontrollieren
Das Schlüsselwort alignas
kann verwendet werden, um eine Variable, ein Klassendatenelement, eine Deklaration oder Definition einer Klasse oder eine Deklaration oder Definition einer alignas
zu erzwingen, falls dies unterstützt wird. Es gibt zwei Formen:
-
alignas(x)
, wobeix
ein konstanter Ausdruck ist, gibt dem Objekt die Ausrichtungx
, sofern unterstützt. -
alignas(T)
, wobeiT
ein Typ ist, gibt der Entität eine Ausrichtung entsprechend der Ausrichtungsanforderung vonT
, d. h.,alignof(T)
, sofern unterstützt.
Wenn mehrere alignas
auf dieselbe Entität angewendet werden, gilt der strengste.
In diesem Beispiel wird garantiert, dass der buf
ausgerichtet ist, um ein int
Objekt aufzunehmen, auch wenn sein Elementtyp unsigned char
buf
ist, die möglicherweise eine schwächere Ausrichtung erfordern.
alignas(int) unsigned char buf[sizeof(int)];
new (buf) int(42);
alignas
kann nicht verwendet werden, um einem Typ eine kleinere Ausrichtung zu geben, als der Typ ohne diese Deklaration haben würde:
alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte.
alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`.
alignas
, wenn ein ganzzahliger konstanter Ausdruck angegeben wird, eine gültige Ausrichtung erhalten. Gültige Ausrichtungen sind immer Zweierpotenzen und müssen größer als Null sein. Compiler müssen alle gültigen Alignments bis zum Alignment vom Typ std::max_align_t
. Sie unterstützen möglicherweise größere Ausrichtungen als diese, aber die Unterstützung für die Zuweisung von Speicher für solche Objekte ist begrenzt. Die Obergrenze für Alignments hängt von der Implementierung ab.
C ++ 17 bietet eine direkte Unterstützung in operator new
für die Zuweisung von Speicher für übergeordnete Typen.