構造レイアウトは実装定義です。そして、たとえば GCC で使用されるデフォルトのレイアウトは、MSVC で使用されるレイアウトとは異なることが判明しました。MSVC がビットフィールドを含む構造体をレイアウトする方法に慣れていると思います。
ms_struct
もちろん、動作を変更できるGCC 属性があります。これについては、ドキュメントで詳しく説明されています。
したがって、この構造体のサイズは 16 です。
struct abc
{
char arr[7];
char arr1[2];
int i:24;
} __attribute__((ms_struct));
デフォルトのオプションを使用するgcc_struct
場合、サイズは 12 です。
特定の実装について、特定のコンパイラ (GCC など) が構造体にパディングを導入する方法を説明するドキュメントはどこで入手できますか?
各コンパイラのドキュメントを参照する必要があります。GCC の場合、ドキュメントには次のように記載されています。
4.9 構造体、共用体、列挙、およびビットフィールド
ユニオン オブジェクトのメンバーは、異なる型のメンバーを使用してアクセスされます (C90 6.3.2.3)。
オブジェクトの表現の関連するバイトは、アクセスに使用されるタイプのオブジェクトとして扱われます。タイプパニングを参照してください。これはトラップ表現である可能性があります。
「プレーンな」int ビットフィールドが signed int ビットフィールドとして扱われるか、unsigned int ビットフィールドとして扱われるか (C90 6.5.2、C90 6.5.2.1、C99 6.7.2、C99 6.7.2.1)。
デフォルトでは、signed int として扱われますが、これは -funsigned-bitfields オプションで変更できます。
_Bool、signed int、および unsigned int (C99 6.7.2.1) 以外の許容されるビット フィールド型。
厳密に適合するモードでは、他のタイプは許可されません。
ビット フィールドがストレージ ユニットの境界をまたぐことができるかどうか (C90 6.5.2.1、C99 6.7.2.1)。
ABI によって決定されます。
ユニット内のビットフィールドの割り当て順序 (C90 6.5.2.1、C99 6.7.2.1)。
ABI によって決定されます。
構造体の非ビット フィールド メンバーのアラインメント (C90 6.5.2.1、C99 6.7.2.1)。
ABI によって決定されます。
各列挙型と互換性のある整数型 (C90 6.5.2.2、C99 6.7.2.2)。
通常、列挙に負の値がない場合、型は unsigned int であり、それ以外の場合は int です。-fshort-enums が指定されている場合、負の値がある場合、すべての値を表すことができるのは、signed char、short、および int の最初のものであり、それ以外の場合は、すべてを表すことができる unsigned char、unsigned short、および unsigned int の最初のものです。その価値。
一部のターゲットでは、-fshort-enums がデフォルトです。これは ABI によって決定されます。
したがって、概して、プラットフォームの ABI が何であるかを理解する必要があります。これは、どのコンパイラにとっても正気なことです。ABI に従って構造体をレイアウトしないと、相互運用が非常に難しくなります。
少し奇妙なのは、Windows での ABI とは何かに関する GCC の見解が、MSVC の実装とは異なることです。なぜそうなのかについての洞察はありません。