强制 C++ 结构紧密包装

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21092415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:28:43  来源:igfitidea点击:

Force C++ structure to pack tightly

c++struct

提问by steveo225

I am attempting to read in a binary file. The problem is that the creator of the file took no time to properly align data structures to their natural boundaries and everything is packed tight. This makes it difficult to read the data using C++ structs.

我正在尝试读取二进制文件。问题是文件的创建者没有花时间将数据结构正确对齐到它们的自然边界,并且所有内容都打包得很紧。这使得使用 C++ 结构读取数据变得困难。

Is there a way to force a structto be packed tight?

有没有办法强制 astruct打包紧?

Example:

例子:

struct {
    short a;
    int b;
}

The above structure is 8 bytes: 2 for short a, 2 for padding, 4 for int b. However, on disk, the data is only 6 bytes (not having the 2 bytes of padding for alignment)

上面的结构是 8 个字节:2 为short a,2 为填充,4 为int b. 但是,在磁盘上,数据只有 6 个字节(没有用于对齐的 2 个填充字节)

Please be aware the actual data structures are thousands of bytes and many fields, including a couple arrays, so I would prefer not to read each field individually.

请注意实际的数据结构是数千字节和许多字段,包括几个数组,所以我不想单独读取每个字段。

回答by legends2k

If you're using GCC, you can do struct __attribute__ ((packed)) { short a; int b; }

如果你使用 GCC,你可以这样做 struct __attribute__ ((packed)) { short a; int b; }

On VC++ you can do #pragma pack(1). This option is also supported by GCC.

在 VC++ 上,您可以执行#pragma pack(1). GCC 也支持此选项。

#pragma pack(push, 1)
struct { short a; int b; }
#pragma pack(pop)

Other compilers may have options to do a tight packing of the structure with no padding.

其他编译器可能可以选择对结构进行紧密打包而没有填充。

回答by John Dibling

You need to use a compiler-specific, non-Standard directive to specify 1-byte packing. Such as under Windows:

您需要使用特定于编译器的非标准指令来指定 1 字节打包。如在Windows下:

#pragma pack (push, 1)

The problem is that the creator of the file took no time to properly byte align the data structures and everything is packed tight.

问题是文件的创建者没有花时间正确地字节对齐数据结构,并且所有内容都打包得很紧。

Actually, the designer did the right thing. Padding is something that the Standard says can be applied, but it doesn't say how much padding should be applied in what cases. The Standard doesn't even say how many bits are in a byte. Even though you might assume that even though these things aren't specified they should still be the same reasonable value on modern machines, that's simply not true. On a 32-bit Windows machine for example the padding might be one thing whereas on the 64-bit version of Windows is might be something else. Maybe it will be the same -- that's not the point. The point is you don't know what the padding will be on different systems.

事实上,设计师做对了。填充是标准说可以应用的东西,但它没有说明在什么情况下应该应用多少填充。该标准甚至没有说明一个字节中有多少位。即使您可能认为即使这些东西没有被指定,它们在现代机器上仍然应该是相同的合理值,但事实并非如此。例如,在 32 位 Windows 机器上,填充可能是一回事,而在 64 位版本的 Windows 上可能是另一回事。也许它会是一样的——这不是重点。关键是你不知道不同系统上的填充是什么。

So by "packing it tight" the developer did the only thing they could -- use some packing that he can be reasonably sure that every system will be able to understand. In that case that commonly-understood packing is to use no padding in structures saved to disk or sent down a wire.

因此,通过“紧密打包”,开发人员做了他们唯一能做的事情——使用一些他可以合理确定每个系统都能够理解的打包方式。在那种情况下,通常理解的打包是在保存到磁盘或发送到电线的结构中不使用填充。