如果我对结构的字段进行布局以使它们不需要任何填充,那么合格的C ++编译器是否还能添加额外的内容?

马丁·马丁

我想用C ++将数据包格式化为现有的二进制协议格式(我正在编写内存缓存客户端)。在C语言中,我可以这样做:

    typedef struct {
        uint8_t magic;
        uint8_t opcode;
        uint16_t keylen;
        uint8_t extlen;
        uint8_t datatype;
        uint16_t reserved;
        uint32_t bodylen;
        uint32_t opaque;
        uint64_t cas;
    } request_header;

通常,在C ++中,编译器可以在字段之间添加填充。但是,上面的结构经过精心布局,因此假设n位类型只需要在n位边界上对齐,则所有内容都可以不进行填充而对齐。因此,按照标准,在C ++中,我安全吗?还是合格的C ++编译器可以增加额外的填充,从而妨碍我使用此功能来布局我的位的能力?

x

没错,C ++可以任意填充。从C ++。11§9.2¶14(强调是我的):

分配具有相同访问控制(第11条)的(非联盟)类的非静态数据成员,以便以后的成员在类对象中具有更高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序(11)。实现一致性要求可能导致两个相邻的成员不能彼此紧接着分配; 管理虚拟功能(10.3)和虚拟基类(10.1)的空间要求也可能如此。

还允许C添加填充字节,因此C ++并不特殊。根据C.11§6.7.2.1¶15(强调是我的):

在结构对象中,非位字段成员和位字段所在的单元的地址按照声明的顺序增加。指向经过适当转换的结构对象的指针指向其初始成员(或者,如果该成员是位字段,则指向它所驻留的单元),反之亦然。结构对象中可能存在未命名的填充,但在其开始时没有。

如果要避免填充,唯一的最大可移植方法是vector在发送时将数据结构自己打包到连续的内存(例如a )中,并在接收时将序列化的数据解包到您的数据结构中。编译器可提供扩展,让你保持所有成员中的struct连续的(例如,GCC的packed属性,或VC ++的pack编译,如所描述这里)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档