サーチ…
前書き
C ++のすべての型は整列しています。これは、そのタイプのオブジェクトを作成できるメモリアドレスの制限です。そのアドレスをオブジェクトの整列で割ると整数である場合、メモリアドレスはオブジェクトの作成に有効です。
型の整列は常に2の累乗です(1を含む)。
備考
標準では、次のことが保証されています。
- 型の整列要件は、そのサイズの約数です。たとえば、サイズが16バイトのクラスは、1,2,4,8,16のいずれかのアライメントを持つことができますが、32ではできません(クラスのメンバーのサイズは合計14バイトですが、クラスはアラインメント要件を持つ必要があります)コンパイラは、2のパディングバイトを挿入して、クラスのサイズを16にします)。
- 整数型の符号付きバージョンと符号なしバージョンのアラインメント要件は同じです。
-
void
へのポインターは、char
へのポインターと同じ位置合わせ要件を持ちます。 - 型のcv-qualifiedバージョンとcv-unqualifiedバージョンは、同じ位置合わせ要件を持ちます。
アライメントはC ++ 03に存在するが、C ++ 11まではアラインメント( alignof
を使用)とアライメントの制御( alignas
を使用)が可能になるまでではなかったことに注意してください。
型の配置の照会
型の整列要件は、単項演算子としてのalignof
キーワードを使用して照会できます。結果は、型std::size_t
定数式です。 つまり、コンパイル時に評価できます。
#include <iostream>
int main() {
std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}
可能な出力
intの整列要件は次のとおりです。
配列に適用すると、要素タイプの配置要件が生成されます。参照型に適用すると、参照型の整列要件が生成されます。 (オブジェクト自体ではないため、参照自体にアラインメントがありません。)
アラインメントの制御
alignas
キーワードを使用すると、変数、クラスデータメンバー、クラスの宣言または定義、または列挙型の宣言または定義を、特定の配置(サポートされている場合)にすることができます。それは2つの形式で来る:
-
alignas(x)
、x
定数式では、エンティティに配向与えるx
サポートしている場合、。 -
alignas(T)
T
型では、エンティティにのアライメント要件に等しい配向与えるT
すなわち、ある、alignof(T)
サポートされている場合、。
同じエンティティに複数のalignas
指定子が適用されている場合、最も厳しいものが適用されます。
この例では、バッファbuf
は、その要素型がunsigned char
であっても、 int
オブジェクトを保持するために適切に整列されていることが保証されています。
alignas(int) unsigned char buf[sizeof(int)];
new (buf) int(42);
alignas
を使用して、この宣言なしで型が持つより小さい整列を型に与えることはできません:
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
は、整数定数式が与えられたとき、有効なアライメントを与えなければならない。有効な整列は常に2のべき乗であり、0より大きくなければなりません。コンパイラは、 std::max_align_t
型の整列まですべての有効な整列をサポートする必要があります。これらは 、これより大きな整列をサポートすることがありますが、そのようなオブジェクトのメモリの割り当てのサポートは限られています。アライメントの上限は実装に依存します。
C ++ 17では、オーバーライドされた型のメモリを割り当てるためにoperator new
直接サポートしています。