align (C++)align (C++)

Visual Studio 2015 以降では、c++ 11 標準を使用して、alignasコントロールの配置を指定子。In Visual Studio 2015 and later, use the C++11 standard alignas specifier to control alignment. 詳細については、配置を参照してください。For more information, see Alignment.

Microsoft 固有の仕様Microsoft Specific

ユーザー定義データ (関数の静的割り当てや自動データなど) のアラインメントを正確に制御するには、__declspec(align(#)) を使用します。Use __declspec(align(#)) to precisely control the alignment of user-defined data (for example, static allocations or automatic data in a function).

構文Syntax

__declspec( align( # ) ) declarator__declspec( align( # ) ) declarator

RemarksRemarks

最新のプロセッサ命令を使用するアプリケーションの記述では、いくつかの新しい制約や問題があります。Writing applications that use the latest processor instructions introduces some new constraints and issues. 特に、多くの新しい命令では、データを 16 バイト境界にアラインする必要があります。In particular, many new instructions require that data must be aligned to 16-byte boundaries. また、頻繁に使用されるデータを特定のプロセッサのキャッシュ ラインのサイズにアラインすることで、キャッシュ パフォーマンスが向上します。Additionally, by aligning frequently used data to the cache line size of a specific processor, you improve cache performance. たとえば、サイズが 32 バイト未満の構造体を定義する場合、その構造体型のオブジェクトが効率的にキャッシュされるように、その構造体を 32 バイトにアラインできます。For example, if you define a structure whose size is less than 32 bytes, you may want to align it to 32 bytes to make sure that objects of that structure type are efficiently cached.

# アラインメント値です。# is the alignment value. 有効なエントリは、1 ~ 8192 (バイト) の 2 の整数乗 (2、4、8、16、32、64 など) です。Valid entries are integer powers of two from 1 to 8192 (bytes), such as 2, 4, 8, 16, 32, or 64. declarator は、aligned として宣言するデータです。declarator is the data that you are declaring as aligned.

型の値を返す方法についてはsize_t型のアラインメント要件を参照してください_ _alignofします。For information about how to return a value of type size_t that is the alignment requirement of the type, see __alignof. 64 ビット プロセッサを対象とするときにアラインされていないポインターを宣言する方法については、次を参照してください。 _ _unalignedします。For information about how to declare unaligned pointers when targeting 64-bit processors, see __unaligned.

使用することができます__declspec(align(#))を定義するとき、構造体共用体、またはクラス変数を宣言する場合またはします。You can use __declspec(align(#)) when you define a struct, union, or class, or when you declare a variable.

コンパイラは、コピーまたはデータ変換の処理中に、データのアラインメント属性の保持を保証したり、保持しようとしません。The compiler does not guarantee or attempt to preserve the alignment attribute of data during a copy or data transform operation. たとえば、 memcpyで宣言された構造体をコピーできます__declspec(align(#))任意の場所にします。For example, memcpy can copy a struct declared with __declspec(align(#)) to any location. 通常に注意してくださいアロケーター — たとえば、 malloc、C++ new 演算子、および Win32 アロケーター — は通常、適切にアラインされないのメモリを返す__declspec(align(#))構造体や配列の構造体。Note that ordinary allocators—for example, malloc, C++ operator new, and the Win32 allocators—return memory that is usually not sufficiently aligned for __declspec(align(#)) structures or arrays of structures. コピーまたはデータの変換操作のコピー先が正しく整列されていることを保証するには使用_aligned_malloc、または独自のアロケーターを記述します。To guarantee that the destination of a copy or data transformation operation is correctly aligned, use _aligned_malloc, or write your own allocator.

関数パラメーターのアラインメントは指定できません。You cannot specify alignment for function parameters. アラインメント属性を持つデータがスタック上で値によって渡されるときに、そのアラインメントは呼び出し規約によって制御されます。When data that has an alignment attribute is passed by value on the stack, its alignment is controlled by the calling convention. 呼び出された関数でデータのアラインメントが重要な場合は、使用する前にパラメーターを正常にアラインされたメモリにコピーします。If data alignment is important in the called function, copy the parameter into correctly aligned memory before use.

せず__declspec(align(#))コンパイラは一般にターゲット プロセッサと最大で 32 ビットのプロセッサで 4 バイト境界、データのサイズに基づいて、自然な境界と 64 ビット プロセッサ、8 バイト境界上のデータを配置します。Without __declspec(align(#)), the compiler generally aligns data on natural boundaries based on the target processor and the size of the data, up to 4-byte boundaries on 32-bit processors, and 8-byte boundaries on 64-bit processors. クラスまたは構造体のデータは、自然なアラインメントと現在のパッキング設定 (#pragma pack または /Zp コンパイラ オプションから) のうちの最小値でクラスまたは構造体内でアラインされます。Data in classes or structures is aligned in the class or structure at the minimum of its natural alignment and the current packing setting (from #pragma pack or the /Zp compiler option).

__declspec(align(#)) を使用する例を次に示します。This example demonstrates the use of __declspec(align(#)):

__declspec(align(32)) struct Str1{
   int a, b, c, d, e;
};

この型には、32 バイト アラインメント属性が設定されました。This type now has a 32-byte alignment attribute. これは、すべての静的および自動インスタンスが 32 バイト境界で開始されることを意味します。This means that all static and automatic instances start on a 32-byte boundary. この種類のメンバーとして宣言されている追加の構造体の型がこの型のアラインメント属性を保持する、構造体は、Str1ように、少なくとも 32 のアラインメント属性を持つ要素。Additional structure types declared with this type as a member preserve this type's alignment attribute, that is, any structure with Str1 as an element has an alignment attribute of at least 32.

sizeof(struct Str1) が 32 と等しいことに注意してください。Note that sizeof(struct Str1) is equal to 32. このため、Str1 オブジェクトの配列が作成されて、配列のベース アドレスが 32 バイトでアラインされる場合、配列の各メンバーも 32 バイトでアラインされます。This implies that if an array of Str1 objects is created, and the base of the array is 32-byte aligned, each member of the array is also 32-byte aligned. 動的メモリでは、ベースが正しくアラインされた配列を作成するには、使用_aligned_malloc、または独自のアロケーターを記述します。To create an array whose base is correctly aligned in dynamic memory, use _aligned_malloc, or write your own allocator.

構造体の sizeof 値は、最後のメンバーのオフセットにメンバーのサイズを加え、最大サイズのメンバーのアラインメント値の倍数か、構造体全体のアラインメント値のどちらか大きい方に切り上げた値です。The sizeof value for any structure is the offset of the final member, plus that member's size, rounded up to the nearest multiple of the largest member alignment value or the whole structure alignment value, whichever is larger.

コンパイラは、構造体のアラインメントにこれらの規則を使用します。The compiler uses these rules for structure alignment:

  • __declspec(align(#)) でオーバーライドしない限り、スカラー構造体のメンバーのアラインメントは、そのサイズと現在のパッキング設定の最小値になります。Unless overridden with __declspec(align(#)), the alignment of a scalar structure member is the minimum of its size and the current packing.

  • __declspec(align(#)) でオーバーライドされない限り、構造体のアラインメントは、そのメンバーの個々のアラインメントの最大値になります。Unless overridden with __declspec(align(#)), the alignment of a structure is the maximum of the individual alignments of its member(s).

  • 構造体のメンバーが配置される、親の構造体の先頭からのオフセットは、アラインメントの最小倍数であり、かつ前のメンバーの最後のオフセットに等しいかそれよりも大きくなります。A structure member is placed at an offset from the start of its parent structure which is the smallest multiple of its alignment greater than or equal to the offset of the end of the previous member.

  • 構造体のサイズは、アラインメントの最小倍数であり、かつ最後のメンバーの最後のオフセットに等しいかそれよりも大きくなります。The size of a structure is the smallest multiple of its alignment greater than or equal to the offset of the end of its last member.

__declspec(align(#)) では、単にアラインメントの制限が多くなることがあります。__declspec(align(#)) can only increase alignment restrictions.

詳細については次を参照してください:For more information, see:

align の例align Examples

次の例では、__declspec(align(#)) がデータ構造体のサイズとアラインメントにどのような影響を与えるかを示します。The following examples show how __declspec(align(#)) affects the size and alignment of data structures. この例では、次の定義を前提とします。The examples assume the following definitions:

#define CACHE_LINE  32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))

次の例では、S1 構造体は __declspec(align(32)) を使用して定義されます。In this example, the S1 structure is defined by using __declspec(align(32)). 変数定義または他の型宣言で S1 を使用すると、すべて 32 バイトでアラインされます。All uses of S1 for a variable definition or in other type declarations are 32-byte aligned. sizeof(struct S1) は 32 を返し、S1 では 4 つの整数の保持に必要な 16 バイトの後に 16 バイトのパディングが挿入されます。sizeof(struct S1) returns 32, and S1 has 16 padding bytes following the 16 bytes required to hold the four integers. intメンバーには、4 バイトのアラインメントが必要ですが、構造体自体のアラインメントは 32 として宣言されています。Each int member requires 4-byte alignment, but the alignment of the structure itself is declared to be 32. そのため、全体的なアラインメントは 32 になります。Therefore, the overall alignment is 32.

struct CACHE_ALIGN S1 { // cache align all instances of S1
   int a, b, c, d;
};
struct S1 s1;   // s1 is 32-byte cache aligned

次の例では、sizeof(struct S2) は 16 を返します。これはメンバーのサイズの合計と一致します。この値が最大アラインメント要件の倍数 (8 の倍数) になっているためです。In this example, sizeof(struct S2) returns 16, which is exactly the sum of the member sizes, because that is a multiple of the largest alignment requirement (a multiple of 8).

__declspec(align(8)) struct S2 {
   int a, b, c, d;
};

次の例では、sizeof(struct S3) は 64 を返します。In the following example, sizeof(struct S3) returns 64.

struct S3 {
   struct S1 s1;   // S3 inherits cache alignment requirement
                  // from S1 declaration
   int a;         // a is now cache aligned because of s1
                  // 28 bytes of trailing padding
};

次の例では、a で自然なアラインメントが行われる (この場合は 4 バイトにアラインされる) ことに注意してください。In this example, notice that a has the alignment of its natural type, in this case, 4 bytes. ただし、S1 は 32 バイトでアラインする必要があります。However, S1 must be 32-byte aligned. a がオフセット 32 で開始するように、s1 の次の 28 バイトがパディングされます。Twenty-eight bytes of padding follow a, so that s1 starts at offset 32. 次に、S4S1 のアラインメント要件を継承します。そのアラインメントが構造体に必要な最大アラインメントであるためです。S4 then inherits the alignment requirement of S1, because it is the largest alignment requirement in the structure. sizeof(struct S4) は 64 を返します。sizeof(struct S4) returns 64.

struct S4 {
   int a;
   // 28 bytes padding
    struct S1 s1;      // S4 inherits cache alignment requirement of S1
};

次の 3 つの変数宣言も __declspec(align(#)) を使用します。The following three variable declarations also use __declspec(align(#)). それぞれの場合で、変数は 32 バイトでアラインする必要があります。In each case, the variable must be 32-byte aligned. 配列の場合、配列の各メンバーではなく、配列のベース アドレスが 32 バイトでアラインされます。In the case of the array, the base address of the array, not each array member, is 32-byte aligned. 配列の各メンバーの sizeof 値は __declspec(align(#)) の使用による影響を受けません。The sizeof value for each array member is not affected when you use __declspec(align(#)).

CACHE_ALIGN int i;
CACHE_ALIGN int array[128];
CACHE_ALIGN struct s2 s;

配列の各メンバーをアラインするには、次のようなコードを使用する必要があります。To align each member of an array, code such as this should be used:

typedef CACHE_ALIGN struct { int a; } S5;
S5 array[10];

次の例では、構造体自体のアラインメントと最初の要素のアラインメントによる影響が同じであることに注意してください。In this example, notice that aligning the structure itself and aligning the first element have the same effect:

CACHE_ALIGN struct S6 {
   int a;
   int b;
};

struct S7 {
   CACHE_ALIGN int a;
               int b;
};

S6S7 では、アラインメント、割り当て、サイズの属性が同じです。S6 and S7 have identical alignment, allocation, and size characteristics.

次の例では、a、b、c、および d の開始アドレスのアラインメントは、それぞれ 4、1、4、および 1 です。In this example, the alignment of the starting addresses of a, b, c, and d are 4, 1, 4, and 1, respectively.

void fn() {
   int a;
   char b;
   long c;
   char d[10]
}

メモリがヒープ上に割り当てられる場合のアラインメントは、どの割り当て関数が呼び出されるかによって異なります。The alignment when memory is allocated on the heap depends on which allocation function is called. たとえば、malloc を使用する場合、結果はオペランドのサイズによって決まります。For example, if you use malloc, the result depends on the operand size. 場合arg > = 8、8 バイトでアラインするが、メモリが返されます。If arg >= 8, the memory returned is 8 byte aligned. 場合arg < 8、返されるメモリのアラインメントは、最初の 2 の累乗より小さいargします。If arg < 8, the alignment of the memory returned is the first power of 2 less than arg. たとえば、malloc(7) を使用すると、アラインメントは 4 バイトになります。For example, if you use malloc(7), the alignment is 4 bytes.

__Declspec(align(#)) と新しい型を定義します。Defining New Types with __declspec(align(#))

型のアラインメントを定義できます。You can define a type with an alignment characteristic.

たとえば、定義、structのアラインメント値このように。For example, you can define a struct with an alignment value this way:

struct aType {int a; int b;};
typedef __declspec(align(32)) struct aType bType;

ここで、aTypebTypeは同じサイズ (8 バイト) が型の変数bType32 バイトでアラインされます。Now, aType and bType are the same size (8 bytes) but variables of type bType are 32-byte aligned.

スレッド ローカル ストレージにデータの整列Aligning Data in Thread Local Storage

__declspec(thread) 属性を使用して作成され、イメージ内の TLS セクションに配置された静的なスレッド ローカル ストレージ (TLS: Thread-Local Storage) は、通常の静的データとまったく同じようにアラインメントされます。Static thread-local storage (TLS) created with the __declspec(thread) attribute and put in the TLS section in the image works for alignment exactly like normal static data. TLS データを作成するために、オペレーティング システムは、TLS セクションのサイズのメモリを割り当て、TLS セクションのアラインメント属性に従います。To create TLS data, the operating system allocates memory the size of the TLS section and respects the TLS section alignment attribute.

次の例では、アラインされたデータをスレッド ローカル ストレージに配置するさまざまな方法を示します。This example shows various ways to place aligned data into thread local storage.

// put an aligned integer in TLS
__declspec(thread) __declspec(align(32)) int a;

// define an aligned structure and put a variable of the struct type
// into TLS
__declspec(thread) __declspec(align(32)) struct F1 { int a; int b; } a;

// create an aligned structure
struct CACHE_ALIGN S9 {
   int a;
   int b;
};
// put a variable of the structure type into TLS
__declspec(thread) struct S9 a;

Align のデータのパッキングでの動作How align Works with Data Packing

/Zpコンパイラ オプションおよびpackプラグマ構造体と共用体のメンバーのデータ パッキングの効果があります。この例ではどのように/Zp__declspec(align(#))連携。The /Zp compiler option and the pack pragma have the effect of packing data for structure and union members.This example shows how /Zp and __declspec(align(#)) work together:

struct S {
   char a;
   short b;
   double c;
   CACHE_ALIGN double d;
   char e;
   double f;
};

次の表に、さまざまな /Zp (または #pragma pack) 値での各メンバーのオフセットと共に、それらの値とオフセットの関係を示します。The following table lists the offset of each member under a variety of /Zp (or #pragma pack) values, showing how the two interact.

変数Variable /Zp1/Zp1 /Zp2/Zp2 /Zp4/Zp4 /Zp8/Zp8
aa 00 00 00 00
bb 11 22 22 22
cc 33 44 44 88
dd 3232 3232 3232 3232
ee 4040 4040 4040 4040
ff 4141 4242 4444 4848
sizeof(S)sizeof(S) 6464 6464 6464 6464

詳細については、「/Zp (構造体メンバーの配置)」を参照してください。For more information, see /Zp (Struct Member Alignment).

オブジェクトのオフセットは、前のオブジェクトのオフセットと現在のパッキング設定に基づきます。ただし、オブジェクトに __declspec(align(#)) 属性が設定されていない場合です。その場合は、アラインメントは前のオブジェクトのオフセットとオブジェクトの __declspec(align(#)) 値に基づきます。The offset of an object is based on the offset of the previous object and the current packing setting, unless the object has a __declspec(align(#)) attribute, in which case the alignment is based on the offset of the previous object and the __declspec(align(#)) value for the object.

Microsoft 固有の仕様はここまでEND Microsoft Specific

関連項目See also

__declspec__declspec
ARM ABI 規則の概要Overview of ARM ABI Conventions
x64 ソフトウェア規約x64 software conventions