为什么在 C++ 中编译时,由 char、short 和 char(按此顺序)组成的结构会出现错误?启用 4 字节打包后,会变成 6 字节结构吗?

发布于 2024-09-17 19:09:05 字数 1109 浏览 1 评论 0原文

我以为我理解 C/C++ 如何处理结构成员对齐。但对于 Visual Studio 2008 和 2010 中的特定安排,我得到了奇怪的结果。

具体来说,我发现由 char、short 和 char 组成的结构被编译为 6 字节结构,即使使用 4 或 4 字节结构也是如此。启用 8 字节打包。我不知道为什么会这样。我可以理解 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 用附加字节填充每个字符?

I thought I understood how C/C++ handled struct member alignment. But I'm getting strange results for a particular arrangement in Visual Studio 2008 and 2010.

Specifically, I'm finding that a struct consisting of a char, short, and char is compiled into a 6-byte struct, even with 4- or 8-byte packing enabled. I am at a loss as to why this would be. I can understand a 4-byte struct. I could perhaps understand an 8-byte struct. But I would think that a 6-byte struct would be impossible when 4-byte packing is enabled.

A program that demonstrates the problem is:

#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;
}

The output is:

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 . . .

Can anyone explain why VC is padding each of those chars with an additional byte?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北风几吹夏 2024-09-24 19:09:05

来自 #pragma pack< 的 MSDN 文档< /code>(其中 n 是您设置的值):

成员的对齐方式将在 n 的倍数或成员大小的倍数(以较小者为准)的边界上进行。

sizeof(short) 是两个字节,小于您设置的四个字节的打包值,因此 short 成员与两个字节边界对齐。

最后一个 char (c2) 在其后填充了一个额外的字节,这样当 Alignment 对象放置在数组中时,Short 元素仍然在两字节边界上正确对齐。数组元素是连续的,它们之间不能有填充,因此必须将填充添加到结构的末尾,以确保数组中的正确对齐。

From the MSDN documentation for #pragma pack (where n is the value you set):

The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.

sizeof(short) is two bytes, which is smaller than the packing value of four bytes that you set, so the short member is aligned to a two byte boundary.

The last char (c2) is padded with an extra byte after it so that when Alignment objects are placed in an array, the short element is still correctly aligned on a two-byte boundary. Array elements are contiguous and there can be no padding between them, so padding must be added to the end of the structure in order to ensure proper alignment in arrays.

关于从前 2024-09-24 19:09:05

看来,你确实理解错了。在 Visual Studio 中,您无法通过使用结构打包设置增加任何类型的结构成员的对齐要求。您只能减少它们。

如果您的结构由 char (在 1 字节边界对齐)和 short (在 2 字节边界对齐)对象组成,则使用 4 字节和 8 字节打包设置将具有绝对不会影响您的结构的布局或大小。结果将与 2 字节打包完全相同。该结构的大小为 6 个字节。

在这种情况下唯一有效的打包设置是 1 字节打包设置,它将 short 的对齐要求从 2 降低到 1,并导致 4 字节大小的结构。

Apparently, you indeed misunderstand it. In Visual Studio you cannot increase the alignment requirements for struct members of any type by using the struct packing settings. You can only decrease them.

If your struct consists of char (aligned at 1 byte boundary) and short (aligned at 2 byte boundary) objects, then using 4- and 8-byte packing settings will have absolutely no effect on the layout or size of your structure. The result will be exactly the same as with 2-byte packing. The structure will have size of 6 bytes.

The only packing setting that will have any effect in this case is 1-byte packing setting which will decrease the alignment requirement of short from 2 to 1 and result in 4 byte size of the structure.

巨坚强 2024-09-24 19:09:05

Visual Studio 的 C 编译器使用此命令选项 /Zp[n],其中结构体打包在 n 字节边界上,这就是 #pragma pack 指令的用武之地,结构的成员在 n 倍数的边界上对齐。

The Visual Studio's C compiler with this command option /Zp[n] where a struct is packed on a n-byte boundary, this is where the #pragma pack directive comes in, members of the structure are aligned on a boundary that is multiple of n.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文