首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C中位字段结构中添加额外的位

在C中位字段结构中添加额外的位
EN

Stack Overflow用户
提问于 2019-08-06 06:27:15
回答 2查看 200关注 0票数 1

我正在尝试为CAPWAP协议创建一个客户端C代码。我尝试使用位字段结构实现CAPWAP头。但是在使用sendto()通过套接字发送这个结构之后,当我使用wireshark嗅探数据包时,我发现在中间添加了一些额外的比特。我不知道这是从哪里来的。请求帮助。提前谢谢。

我试着对结构的最后几个成员进行注释,以使其对齐4字节。但这一现象依然存在。

这是原始的标题

代码语言:javascript
复制
struct cw_header
{
unsigned preamble : 8;
unsigned hlen : 5;
unsigned rid : 5;
unsigned wbid : 5;
unsigned t : 1;
unsigned f : 1;
unsigned l : 1;
unsigned w : 1;
unsigned m : 1;
unsigned k : 1;
unsigned flags : 3;
unsigned fragment_id : 16;
unsigned fragment_offset : 13;
unsigned reserved : 3;
uint32_t mac_length : 8;
uint32_t mac_addr[6];
uint32_t padding : 8;
};

我试着评论这些

代码语言:javascript
复制
//uint32_t mac_length : 8;
//uint32_t mac_addr[6];
//uint32_t padding : 8;

这是结构被填充的地方。

代码语言:javascript
复制
struct cw_header create_cw_header()
{
struct cw_header cw_header;
cw_header.preamble = 0;
cw_header.hlen = 1;
cw_header.rid = 1;
cw_header.wbid = 1; 
cw_header.t = 0;
cw_header.f = 0;
cw_header.l = 1;
cw_header.w = 0;
cw_header.m = 1;
cw_header.k = 0;
cw_header.flags = 0;    
cw_header.fragment_id = 0;  ;
cw_header.fragment_offset = 0;  
cw_header.reserved = 0; 
cw_header.mac_length = 6;
get_mac_address(cw_header.mac_addr);
cw_header.padding = 0;
return cw_header;
};

以下是wireshark对前32位的输出

代码语言:javascript
复制
0000 0000 0010 0001 0000 0100 0000 1010 

预期结果:位应该按照结构错误中提到的顺序排列:在struct成员之间添加额外的位

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-06 06:48:45

位应按照结构中提到的顺序排列

什么命令?C语言没有指定位的顺序。您无法轻松地知道preamble是MSB还是LSB。

“在结构成员之间添加额外的位”

是的,编译器可以自由地在位字段的成员之间放置填充位或填充字节。Bitfield被抽象地划分为“不可见的”单元(按标准称为“存储单元”),这些单元具有给定的大小--通常与CPU对齐的大小相同,但不一定如此。在不同的这样的存储单元之间,可能存在也可能没有填充。编译器也可以自由地将不适合一个存储单元的位放在下一个存储单元中。

如果不阅读编译器的位字段实现,就无法知道特定的编译器将做什么。按照C标准,几乎没有对它们的支持。

在此基础上添加endianess,您就会有一个适当的混乱--在您的情况下,CPU权限和网络权限都很重要。

所有这些问题的最佳解决方案是完全删除位字段。相反,您应该使用更明确、更具确定性和可移植性的按位运算符:

代码语言:javascript
复制
uint32_t cw_preable = something << preamble_offset;
...
uint32_t cw_header = 0;
cw_header |= cw_preamble;
...
票数 5
EN

Stack Overflow用户

发布于 2019-08-06 06:47:08

位字段的布局完全是implementation-dependent.。但是,通常情况下,一个单元不能跨越存储单元边界,因此在这种情况下,它将取决于unsigned的大小。它还取决于uint32_t的定义方式和与其他所有内容的比较,以及uint32_t mac_addr[6];是否可以在uint32_t : 8中覆盖存储单元的其余部分。

总之,它不会很漂亮。最好的操作方法是在结构中使用命名的unsigned char/uint8_t字段和数组,将较小的成员打包到这些字段和数组中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57370069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档