我想用C格式化现有二进制协议格式的数据包(我正在编写一个memcached客户端).在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编译器是否可以添加额外的填充,阻止我使用它来布置我的位?
解决方法
你是对的,C可以任意填充.从C.11§9.2?14(重点是我的):
Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (11). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
C也允许添加填充字节,因此这不是C的特殊之处.从C.11§6.7.2.1?15(重点是我的):
Within a structure object,the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object,suitably converted,points to its initial member (or if that member is a bit-field,then to the unit in which it resides),and vice versa. There may be unnamed padding within a structure object,but not at its beginning.
如果要避免填充,唯一最便携的方法是在发送时将数据结构自己打包到连续的内存(例如,向量)中,并在接收时将序列化数据解压缩到数据结构中.您的编译器可能提供扩展,允许您将结构中的所有成员保持连续(例如,GCC的压缩属性或VC的包编译指示,如here所述).
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|