特定のデータ型のバイト アライメント要件は、2 の累乗であることが保証されていますか?
システムページサイズと一致しないため、「そうでなければ意味がない」以外に、この保証を提供するものはありますか?
(背景: C/C++ であるため、データ型が C または C++ 型であると仮定して、C/C++ 固有の回答を提供してください。)
特定のデータ型のバイト アライメント要件は、2 の累乗であることが保証されていますか?
システムページサイズと一致しないため、「そうでなければ意味がない」以外に、この保証を提供するものはありますか?
(背景: C/C++ であるため、データ型が C または C++ 型であると仮定して、C/C++ 固有の回答を提供してください。)
アライメント要件はハードウェアに基づいています。すべてではないにしても、ほとんどの「最新の」チップには、2 のべき乗だけでなく、8 で割り切れるアドレスがあります。以前は、8 チップで割り切れないアドレスがありました (私は 36 ビット アーキテクチャを知っています)。
C標準に従って、アライメントについて想定できること:
sizeof
ます)。char
、signed char
、およびunsigned char
には位置合わせ要件はありません。(これは実際には、最初のポイントの特殊なケースです。)long long
現代の実世界では、整数型とポインター型のサイズは 2 の累乗であり、それらのアライメント要件は通常、それらのサイズと同じです ( 32 ビット マシンの場合は例外です)。浮動小数点は少し均一ではありません。32 ビット マシンでは、通常、すべての浮動小数点型のアラインメントは 4 ですが、64 ビット マシンでは、浮動小数点型のアラインメント要件は通常、型のサイズ (4、8、または 16) と同じです。
astruct
のアラインメント要件は、そのメンバーのアラインメント要件の最小公倍数でなければなりませんが、コンパイラはより厳密なアラインメントを課すことができます。ただし、通常、各 CPU アーキテクチャにはアライメント規則を含む ABI 標準があり、標準に準拠していないコンパイラは、ABI 標準に従うコンパイラによってビルドされたコードとリンクできないコードを生成するため、非常にまれです。非常に特殊な目的の使用を除いて、標準から逸脱するコンパイラ。
ちなみに、正常なコンパイラで動作する便利なマクロは次のとおりです。
#define alignof(T) ((char *)&((struct { char x; T t; } *)0)->t - (char *)0)
要するに、違います。ハードウェアによって異なります。
ただし、最新のCPUのほとんどは、バイトアラインメント(Intel x86 CPUなど)またはワードアラインメント(Motorola、IBM / 390、RISCなど)のいずれかを実行します。
単語の配置があっても、複雑になる可能性があります。たとえば、16ビットワードは2バイト(偶数)アドレスにアラインされ、32ビットワードは4バイト境界にアラインされますが、64ビット値は8バイトではなく4バイトアラインメントのみを必要とする場合があります。 -バイトアラインされたアドレス。
バイトアラインされたCPUの場合、これはコンパイラオプションの機能でもあります。構造体メンバーのデフォルトのalignmenは、通常、指定できます(通常、コンパイラー固有の#pragmaも指定できます)。
サイズが最適化された「構造体」内のフィールドの配置は、奇妙な境界上にある可能性が非常に高いです。あなたの「意味がない」ということ以外はおそらく当てはまりますが、特にプログラムがサイズに最適化された小さなモデルである場合、保証はないと思います。- ジョー
標準ではアラインメントは必要ありませんが、構造体/共用体/ビット フィールドがパディング バイトを静かに追加して正しいアラインメントを取得することを許可します。コンパイラは、必要に応じて、すべてのデータ型を偶数アドレスに自由に配置することもできます。
そうは言っても、これは CPU に依存しており、奇数アドレスにアラインメント要件がある CPU は存在しないと思います。ただし、アラインメント要件のないCPU はたくさんあり、コンパイラは変数を任意のアドレスに配置する可能性があります。
基本的なデータ型 (int、float、ダブルス) 通常、アラインメントは型のサイズと一致します。クラス/構造体の場合、アラインメントは少なくともそのすべてのメンバーのアラインメントの最小公倍数です (これが標準です)。
Visual Studio では、型に対して独自の配置を設定できますが、1 から 8192 までの 2 のべき乗である必要があります。
GCCにも同様のメカニズムがありますが、そのような要件はありません(少なくとも理論的には)