如果结构只包含字节数组,那么“pragma pack(1)”是否有风险/危险

如果结构只包含字节数组,那么“pragma pack(1)”是否有风险/危险,c,casting,pragma-pack,C,Casting,Pragma Pack,在仅包含字节数组的结构上使用#pragma pack(1)是否危险?例如,这个: #pragma pack(1) struct RpcMessage { uint8_t proto_info[16]; uint8_t message_uuid[16]; uint8_t arg0[16]; uint8_t arg1[16]; uint8_t arg2[16]; uint8_t arg3[16]; uint8_t arg4[16];

在仅包含字节数组的结构上使用
#pragma pack(1)
是否危险?例如,这个:

#pragma pack(1)
struct RpcMessage {
    uint8_t proto_info[16];
    uint8_t message_uuid[16];

    uint8_t arg0[16];
    uint8_t arg1[16];
    uint8_t arg2[16];
    uint8_t arg3[16];
    uint8_t arg4[16];
    uint8_t arg5[16];
    uint8_t arg6[16];
    uint8_t arg7[16];

    uint8_t payload[65376];
};

(想法是直接将此结构强制转换为2^16原始I/O字节或从中转换为2^16原始I/O字节,而不存在任何不兼容甚至错误)

如果该结构仅包含
uint8\u t
,则
pragma pack(1)
将完全无效。它根本不会做任何事情,因为结构已经被尽可能紧密地打包


只有当元素的对齐方式大于字节对齐方式时,才会出现填充

如果结构仅包含
uint8\u t
,则
#pragma pack(1)
将完全无效。它根本不会做任何事情,因为结构已经被尽可能紧密地打包



只有当元素的对齐方式大于字节对齐方式时,才会出现填充

假设每个数组的大小是对齐的倍数,
#pragma pack
不会做任何事情,因为每个数组将自动正确对齐。

假设每个数组的大小是对齐的倍数,
#pragma pack
不会做任何事情,因为每个阵列将自动正确对齐。

本身没有风险或危险;只是没必要。如果所有内容都是一个字节数组,那么元素之间就不会有填充,因此pragma毫无意义(无害,但毫无意义)。据我所知,打包的唯一问题是,正在进行未对齐的传输,这会增加必要的汇编指令的数量。@FiddlingBits:结构的对齐要求在任何合理的ABI上都已为1,因此不会有任何区别。@R对。应该提到如果大于一个字节。pragma和属性是一个讨厌的东西,应该只在绝对必要时使用。他们将C语言(一种设计良好的语言,能够在标准团体的攻击下生存下来)转换成自己设计的语言;只是没必要。如果所有内容都是一个字节数组,那么元素之间就不会有填充,因此pragma毫无意义(无害,但毫无意义)。据我所知,打包的唯一问题是,正在进行未对齐的传输,这会增加必要的汇编指令的数量。@FiddlingBits:结构的对齐要求在任何合理的ABI上都已为1,因此不会有任何区别。@R对。应该提到如果大于一个字节。pragma和属性是一个讨厌的东西,应该只在绝对必要时使用。他们将C语言(一种设计良好的语言,能够在标准团体的攻击下生存下来)转换成自己设计的语言;uint8_t y[n]。编译器可能希望在对齐的地址上分配
y
,以获得更好的性能,在这种情况下,可以在
x
y
之间自由插入空格@Lundin:也许这在技术上是正确的,但这显然表明设计编译器的人讨厌你,希望看到你失败。据我所知,@Lundin所声称的在现代使用的任何ABI上都是不正确的。我也是,这只是那些理论上的语言律师评论之一:)尽管我们不需要看太远就能找到编译器喜欢在对齐地址上分配数组的情况:只需看一下局部变量。这在
uint8_t x[3]的情况下不一定是正确的;uint8_t y[n]。编译器可能希望在对齐的地址上分配
y
,以获得更好的性能,在这种情况下,可以在
x
y
之间自由插入空格@Lundin:也许这在技术上是正确的,但这显然表明设计编译器的人讨厌你,希望看到你失败。据我所知,@Lundin所声称的在现代使用的任何ABI上都是不正确的。我也是,这只是那些理论上的语言律师的评论之一:)尽管我们不需要看太远就能找到编译器喜欢在对齐地址上分配数组的情况:只需看一下局部变量。