1. ホーム
  2. c

[解決済み】#pragma pack の効果

2022-04-29 21:31:16

質問

を説明できる人がいたら教えてください。 #pragma pack プリプロセッサー文は何をするのか、そしてもっと重要なのは、なぜそれを使いたいのか、ということです。

を調べてみると MSDNページ しかし、経験者の意見をもっと聞きたいと思っていました。以前、コードで見たことがあるのですが、もうどこで見たのかわからないようです。

解決方法は?

#pragma pack は、構造体のメンバを特定のアライメントでパックするようコンパイラに指示します。 ほとんどのコンパイラは、構造体を宣言すると、メンバの間にパディングを挿入して、メモリ内の適切なアドレス(通常は型のサイズの倍数)にアライメントされるようにします。 これにより、アーキテクチャによっては、適切にアラインされていない変数にアクセスした場合に発生する性能低下(または明らかなエラー)を回避することができます。 例えば、4バイトの整数と次のような構造体があったとします。

struct Test
{
   char AA;
   int BB;
   char CC;
};

コンパイラは、構造体をこのようにメモリ上に配置することを選択できます。

|   1   |   2   |   3   |   4   |  

| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) | 
| CC(1) | pad.................. |

sizeof(Test) は、6バイトのデータしか入っていないのに、4×3=12となります。 最も一般的な使用例としては #pragma (私の知る限り)ハードウェアデバイスを扱う場合、コンパイラがデータにパディングを挿入せず、各メンバーが前のメンバーに続くことを確認する必要があります。 この場合 #pragma pack(1) であれば、上の構造体はこのようなレイアウトになります。

|   1   |

| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |

そして sizeof(Test) は1×6=6となる。

#pragma pack(2) の場合、上の構造体はこのようにレイアウトされます。

|   1   |   2   | 

| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |

そして sizeof(Test) は2×4=8となる。

構造体内部の変数の順番も重要です。

struct Test
{
   char AA;
   char CC;
   int BB;
};

とのことです。 #pragma pack(2) というように、構造体がレイアウトされます。

|   1   |   2   | 

| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |

sizeOf(Test) は3×2=6となる。