#pragma pack in C++

发布于 2024-10-08 21:29:38 字数 90 浏览 7 评论 0原文

为什么 C++ 中的 typedef 结构需要 #pragma pack ?特别是当您在网络通信中使用这些结构时。

why do we need to have #pragma pack for typedef structure in C++? Specifically when you are using those structure in network communication.

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

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

发布评论

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

评论(4

蓝咒 2024-10-15 21:29:38

#pragma pack 控制结构成员的对齐方式。常见的默认设置是 8,确保长度最多为 8 字节的成员在其大小的倍数的地址上对齐。例如,双精度或 64 位指针。读取或写入未对齐的双精度值可能会非常昂贵,如果它跨越 CPU 缓存行边界,通常会慢三倍。这种对齐方式会在成员之间产生未使用的空间,称为填充。

这种对齐方式通常不适合网络框架,它们往往紧密包装,没有任何填充,#pragma pack(push, 1)

#pragma pack controls the alignment of members of a structure. The common default setting is 8, ensuring that members that are up to 8 bytes long get aligned on an address that's a multiple of their size. A double or 64-bit pointer for example. Reading or writing a mis-aligned double can be quite expensive, typically three times slower if it straddles a CPU cache line boundary. This alignment can produce unused space between members, called padding.

This kind of alignment is often inappropriate for network frames, they tend to be tightly packed without any padding, #pragma pack(push, 1)

演多会厌 2024-10-15 21:29:38

#pragma pack 指令仅修改其声明遵循该指令的结构成员的当前对齐规则。它不直接影响结构的对齐,但通过影响结构成员的对齐,根据对齐规则可能会影响整体结构的对齐

The #pragma pack directive modifies the current alignment rule for only the members of structures whose declarations follow the directive. It does not affect the alignment of the structure directly, but by affecting the alignment of the members of the structure, it may affect the alignment of the overall structure according to the alignment rule

伴我老 2024-10-15 21:29:38

如果您只需要让具有相同设置的 2 个系统相互通信(测试等),您可以发送结构,前提是它们只是 POD(普通旧数据)(指针、虚拟表、std::strings..不能使用)。所以不需要打包。

如果系统没有相同的设置(或未知),则需要发送以协议序列化的数据,因此打包结构不起作用。检查有效协议是否可用是最简单的。

If you just need to let 2 systems with same setup talk to each other (test,...), you can send structs, provided they are just POD (plain old data) (pointers, virtual tables, std::strings... can't be used). So pack is not needed.

If the systems don't have the same setup (or are not known), you need to send data serialized in a protocol, so packed structures will not do. It is easiest to check whether valid protcols are available.

任谁 2024-10-15 21:29:38

编译器将“填充”结构体的字段和子字段,即用中间不包含任何内容的空白内存块在内存中组织它们。正如汉斯·帕桑特的回答所解释的那样,这样做是为了提高效率。

不同的编译器/目标/优化设置可能会以不同的方式进行填充,以不同的内存表示形式转换相同的“逻辑”结构,因此如果两台通信机器在它们之间传递结构,它们可能无法相互理解。

#pragma pack 是限制编译器填充自由的方法。

#pragma pack(push, 1) 命令编译器根本不填充。如果您对不同代码中定义的两个相同的结构执行此操作,它们将在内存中以相同的方式表示。然后,您可以使用指针和 sizeof() 通过某种协议安全地发送一个应用程序中结构的内容,将其放在另一侧并将其写入相同的结构上,同样使用指针和 sizeof()。

Compilers will "pad" the struct's fields and subfields, i.e., organize them in memory with blank chunks of memory that hold nothing in the middle. It does this to increase efficiency as Hans Passant's answer explains.

Different compilers/targets/optimization settings may pad differently, transforming equal 'logical' structs in unequal memory representations, so if two communicating machines pass the struct between them, they may not understand each other.

#pragma pack is your way to limit the compiler's freedom to pad.

#pragma pack(push, 1) orders the compiler to not pad at all. If you do this to two identical structs defined in different codes, they will be identically represented in memory. Then you can safely send the contents of a struct in one application throught some protocol using a pointer and sizeof(), getting it on the other side and writing it right over an identical struct, also using a pointer and sizeof().

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