4

C /C++が構造体メンバーの配置をどのように処理するかを理解したと思いました。しかし、VisualStudio2008および2010の特定の配置で奇妙な結果が得られています。

具体的には、char、short、およびcharで構成される構造体は、4バイトまたは8バイトのパッキングが有効になっている場合でも、6バイトの構造体にコンパイルされることがわかりました。なぜそうなるのか途方に暮れています。4バイトの構造体が理解できます。おそらく8バイトの構造体を理解できたでしょう。しかし、4バイトのパッキングが有効になっている場合、6バイトの構造体は不可能だと思います。

問題を示すプログラムは次のとおりです。

#include <iostream>
using namespace std;

#pragma pack (4)

struct Alignment
{
 char c1;
 short s;
 char c2;
};

#define REPORT_VAR_POSITION( structName, varName ) cout << "Member '" << #varName << "' sits at byte # " << offsetof( structName, varName ) << "." << endl;

int main(int argc, char* argv[])
{
 cout << "Sizeof struct Alignment is " << sizeof( Alignment ) << " bytes." << endl;
 REPORT_VAR_POSITION( Alignment, c1 );
 REPORT_VAR_POSITION( Alignment, s );
 REPORT_VAR_POSITION( Alignment, c2 );

 system( "pause" );

 return 0;
}

出力は次のとおりです。

Sizeof struct Alignment is 6 bytes.
Member 'c1' sits at byte # 0.
Member 's' sits at byte # 2.
Member 'c2' sits at byte # 4.
Press any key to continue . . .

VCがこれらの各文字に追加のバイトをパディングしている理由を誰かが説明できますか?

4

3 に答える 3

17

(設定した値はどこにありますか)のMSDNドキュメント#pragma packから:n

nメンバーの配置は、メンバーのサイズの倍数または倍数のいずれか小さい方の境界上になります。

sizeof(short)は2バイトであり、設定した4バイトのパッキング値よりも小さいため、shortメンバーは2バイトの境界に揃えられます。

最後のcharc2)には、その後に余分なバイトが埋め込まれるため、Alignmentオブジェクトが配列に配置された場合shortでも、要素は2バイトの境界に正しく配置されます。配列要素は連続しており、それらの間にパディングはありません。そのため、配列の適切な配置を確保するために、構造の最後にパディングを追加する必要があります。

于 2010-09-03T18:00:19.960 に答える
4

どうやら、あなたは確かにそれを誤解しています。Visual Studioでは、構造体のパッキング設定を使用して、どのタイプの構造体メンバーの配置要件を増やすこともできません。あなたはそれらを減らすことができるだけです。

構造体がchar(1バイト境界でshort整列)オブジェクトと(2バイト境界で整列)オブジェクトで構成されている場合、4バイトと8バイトのパッキング設定を使用しても、構造のレイアウトやサイズにはまったく影響しません。結果は、2バイトのパッキングの場合とまったく同じになります。構造のサイズは6バイトになります。

この場合に影響を与える唯一のパッキング設定は、1バイトのパッキング設定です。これにより、アライメント要件が2から1に減少し、構造のサイズが4バイトになります。short

于 2010-09-03T18:06:32.050 に答える
-1

このコマンドオプション/Zp[n]を使用するVisualStudioのCコンパイラでは、構造体がnバイトの境界にパックされます。これが#pragma packディレクティブの出番であり、構造体のメンバーはnの倍数の境界に配置されます。

于 2010-09-03T18:05:54.813 に答える