3

コード 1:-

struct emp
{
  char a;
  double b;
};
int main()
{
    struct emp e;
    printf("%p    %p", (void*)&e.a, (void*)&e.b);
}

私のコンピューターでの出力:-

OO28FF00    0028FF08

charとのサイズはdoubleそれぞれ '1' と '8' であるため、0028FF000028FF08はそれぞれ '1' と '8' の倍数です。

コード 2:-

struct emp
{
  char a;
  long double b;
};
int main()
{
    struct emp e;
    printf("%p    %p    \n", (void*)&e.a,(void*)&e.b);
}

出力は次のとおりです:-

0028FF00    0028FF04

charとのサイズはlong doubleそれぞれ '1' と '12' ですが0028FF04、'12' の倍数ではありません。

この場合、パディングが適用されないのはなぜですか?

4

3 に答える 3

3

Along double80 ビットの浮動小数点なので、10 バイトが必要です。ただし、10 は実際にはあまり適切なサイズではないため、Intel 32 ビット プロセッサは 12 バイトに決定しました。12 は 4 の倍数で、32 ビット (3 x 32 ビット) を表します。32 ビット プロセッサは 4 バイトのアライメントしか必要としないため、これはアライメントされていると見なされます。したがって、12 バイトは任意の 4 バイト境界でアライメントされます。明らかに、コンパイラは自分が何をしているのかを認識しており、常に可能な限り最小の構造を生成しようとします。

これは、構造体宣言を使用できないことがわかり、ファイルにそのまま保存することを望んでいる場所です...少なくともデフォルトのCタイプではありません(int32_t、uint64_tなどを使用して正確に取得できます必要なものですが、浮動小数点数に相当するものはありません...)

誰かがコメントしたように、64 ビット アーキテクチャでは、long double は 16 バイトです。6バイトの無駄です...しかし、それは型を常に64ビットに揃えます。

于 2014-02-08T07:57:55.397 に答える
0

私の知る限り、パディングとデータのアライメントは、ターゲット アーキテクチャ、コンパイラの最適化オプション、およびオプティマイザの全体的な品質に大きく依存します。したがって、アラインメントを特に気にしない場合、「準最適」な構造が得られ、コンパイラーはこの特定の最適化オプションのセットに対して何が優れているかを自由に決定できます (-Os と -O のどちらを使用するかなど)。 . 特定のアライメントが必要な場合は、コンパイラ固有のオプションを使用して調整する必要があります。GCC と CLang の場合は__packed__属性を使用し、MSVC の場合は を使用します#pragma pack。詳しくはpragma pack(1) や __attribute__ ((aligned (1))) の動作を参照してください

于 2014-02-08T07:48:15.567 に答える