联合内的位填充结构和类型转换
我有一个无符号 64 位字和一个位填充结构,它们都在下面给出。该结构位于一个联合内,其中包含几个(确切地说是 11 个)相似但略有不同的结构。
uint64_t final_data_word;
#pragma pack(1)
typedef struct control_block_format_1_s
{
uint8_t block_type_field:8;
uint8_t control_word_0:7;
uint8_t control_word_1:7;
uint8_t control_word_2:7;
uint8_t control_word_3:7;
uint8_t control_word_4:7;
uint8_t control_word_5:7;
uint8_t control_word_6:7;
uint8_t control_word_7:7;
}control_block_format_1_t;
typedef union
{
control_block_format_1_t *cb_1;
control_block_format_2_t *cb_2;
control_block_format_3_t *cb_3;
control_block_format_4_t *cb_4;
control_block_format_5_t *cb_5;
control_block_format_6_t *cb_6;
control_block_format_7_t *cb_7;
control_block_format_8_t *cb_8;
control_block_format_9_t *cb_9;
control_block_format_10_t *cb_10;
control_block_format_11_t *cb_11;
}block_payload_union_t;
#pragma pack()
我想将 64 位字中的 64 位解释为结构中的字段。所以我正在执行以下操作,
block_payload_union_t *block_pload =(block_payload_union_t*)malloc(sizeof(block_payload_union_t*));
block_pload->cb_1 = (control_block_format_1_t*)(&final_data_word);
但我没有获得结构中最后一个字段的预期值。任何人都可以看到我的内容有任何问题吗?我在做什么?如有任何建议或意见,我们将不胜感激。
@乔纳森 我已将以下注释添加到我的代码中。
printf("sizeof(union) = %zu\n", sizeof(block_payload_union_t));
printf("sizeof(cb1) = %zu\n", sizeof(control_block_format_1_t));
printf("FDW = 0x%.16lx\n", Final_data_word);
//printf("*bp->llp = 0x%.16lx\n", *block_pload->llp);
printf("bp->cb1->block_type_fld = 0x%.2X\n", block_pload->cb_1->block_type_field);
printf("bp->cb1->control_word_0 = 0x%.2X\n", block_pload->cb_1->control_word_0);
printf("bp->cb1->control_word_1 = 0x%.2X\n", block_pload->cb_1->control_word_1);
printf("bp->cb1->control_word_2 = 0x%.2X\n", block_pload->cb_1->control_word_2);
printf("bp->cb1->control_word_3 = 0x%.2X\n", block_pload->cb_1->control_word_3);
printf("bp->cb1->control_word_4 = 0x%.2X\n", block_pload->cb_1->control_word_4);
printf("bp->cb1->control_word_5 = 0x%.2X\n", block_pload->cb_1->control_word_5);
printf("bp->cb1->control_word_6 = 0x%.2X\n", block_pload->cb_1->control_word_6);
printf("bp->cb1->control_word_7 = 0x%.2X\n", block_pload->cb_1->control_word_7);
没有 #pragma pack() 时得到的输出如下
最终数据字 0x1e00000000000000
sizeof(联合) = 8
sizeof(cb1) = 9
FDW = 0x1e00000000000000
bp->cb1->block_type_fld = 0x00
bp->cb1->control_word_0 = 0x00
bp->cb1->control_word_1 = 0x00
bp->cb1->control_word_2 = 0x00
bp->cb1->control_word_3 = 0x00
bp->cb1->control_word_4 = 0x00
bp->cb1->control_word_5 = 0x00
bp->cb1->control_word_6 = 0x1E
bp->cb1->control_word_7 = 0x78
#pragma pack() 的输出如下
最终数据字 0x1e00000000000000
sizeof(联合) = 8
sizeof(cb1) = 8
FDW = 0x1e00000000000000
bp->cb1->block_type_fld = 0x00
bp->cb1->control_word_0 = 0x00
bp->cb1->control_word_1 = 0x00
bp->cb1->control_word_2 = 0x00
bp->cb1->control_word_3 = 0x00
bp->cb1->control_word_4 = 0x00
bp->cb1->control_word_5 = 0x00
bp->cb1->control_word_6 = 0x00
bp->cb1->control_word_7 = 0x0F
这与您在 Jonathan 机器上得到的输出类似。
I have a unsigned 64-bit word and a bit padded structure which are both given below.The structure is inside a union which contains several(11 to be exact) similar but slightly structures.
uint64_t final_data_word;
#pragma pack(1)
typedef struct control_block_format_1_s
{
uint8_t block_type_field:8;
uint8_t control_word_0:7;
uint8_t control_word_1:7;
uint8_t control_word_2:7;
uint8_t control_word_3:7;
uint8_t control_word_4:7;
uint8_t control_word_5:7;
uint8_t control_word_6:7;
uint8_t control_word_7:7;
}control_block_format_1_t;
typedef union
{
control_block_format_1_t *cb_1;
control_block_format_2_t *cb_2;
control_block_format_3_t *cb_3;
control_block_format_4_t *cb_4;
control_block_format_5_t *cb_5;
control_block_format_6_t *cb_6;
control_block_format_7_t *cb_7;
control_block_format_8_t *cb_8;
control_block_format_9_t *cb_9;
control_block_format_10_t *cb_10;
control_block_format_11_t *cb_11;
}block_payload_union_t;
#pragma pack()
I want to interpret the 64 bits in the 64-bit word as fields in the structure.so I am doing the below operation
block_payload_union_t *block_pload =(block_payload_union_t*)malloc(sizeof(block_payload_union_t*));
block_pload->cb_1 = (control_block_format_1_t*)(&final_data_word);
but I am not getting the expected values for the last field in my structure.Can anyone see any problem with what I am doing?Any suggestions or comments are appreciated.
@Jonathan
I have added the following comments to my code.
printf("sizeof(union) = %zu\n", sizeof(block_payload_union_t));
printf("sizeof(cb1) = %zu\n", sizeof(control_block_format_1_t));
printf("FDW = 0x%.16lx\n", final_data_word);
//printf("*bp->llp = 0x%.16lx\n", *block_pload->llp);
printf("bp->cb1->block_type_fld = 0x%.2X\n", block_pload->cb_1->block_type_field);
printf("bp->cb1->control_word_0 = 0x%.2X\n", block_pload->cb_1->control_word_0);
printf("bp->cb1->control_word_1 = 0x%.2X\n", block_pload->cb_1->control_word_1);
printf("bp->cb1->control_word_2 = 0x%.2X\n", block_pload->cb_1->control_word_2);
printf("bp->cb1->control_word_3 = 0x%.2X\n", block_pload->cb_1->control_word_3);
printf("bp->cb1->control_word_4 = 0x%.2X\n", block_pload->cb_1->control_word_4);
printf("bp->cb1->control_word_5 = 0x%.2X\n", block_pload->cb_1->control_word_5);
printf("bp->cb1->control_word_6 = 0x%.2X\n", block_pload->cb_1->control_word_6);
printf("bp->cb1->control_word_7 = 0x%.2X\n", block_pload->cb_1->control_word_7);
The output I got without #pragma pack() was as follows
final data word 0x1e00000000000000
sizeof(union) = 8
sizeof(cb1) = 9
FDW = 0x1e00000000000000
bp->cb1->block_type_fld = 0x00
bp->cb1->control_word_0 = 0x00
bp->cb1->control_word_1 = 0x00
bp->cb1->control_word_2 = 0x00
bp->cb1->control_word_3 = 0x00
bp->cb1->control_word_4 = 0x00
bp->cb1->control_word_5 = 0x00
bp->cb1->control_word_6 = 0x1E
bp->cb1->control_word_7 = 0x78
The output with #pragma pack() was as follows
final data word 0x1e00000000000000
sizeof(union) = 8
sizeof(cb1) = 8
FDW = 0x1e00000000000000
bp->cb1->block_type_fld = 0x00
bp->cb1->control_word_0 = 0x00
bp->cb1->control_word_1 = 0x00
bp->cb1->control_word_2 = 0x00
bp->cb1->control_word_3 = 0x00
bp->cb1->control_word_4 = 0x00
bp->cb1->control_word_5 = 0x00
bp->cb1->control_word_6 = 0x00
bp->cb1->control_word_7 = 0x0F
which is similar to the output you got on Jonathan's machine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该在调用
malloc()
时使用sizeof(block_payload_union_t)
而不是sizeof(block_payload_union_t *)
。然而,在 64 位机器上,它可能会为您提供相同的大小 (8),因此您可以侥幸逃脱,尽管它是错误的。有点奇怪的是,您的 block_payload_union_t 包含指向字段布局的指针而不是保存实际值。
您尚未向我们展示
final_data_word
的声明。您是否检查过工会的规模与您期望的规模?在运行 Lion (10.7.2) 的 Mac 上,我从程序中获得如下输出:
Output
With
#pragma pack(1)
:Without
#pragma pack(1)
:你得到什么?
程序
You should be using
sizeof(block_payload_union_t)
instead ofsizeof(block_payload_union_t *)
in the call tomalloc()
. However, on a 64-bit machine, it probably gives you the same size (8), so you get away with it, for all it is wrong.It is slightly odd that your
block_payload_union_t
contains pointers to your field layouts instead of holding the actual values.You have not shown us the declaration of
final_data_word
. Have you checked the size of your union versus the size you expect?On a Mac running Lion (10.7.2), I get this output from the program which follows:
Output
With
#pragma pack(1)
:Without
#pragma pack(1)
:What are you getting?
Program
让指针作为工会成员有什么意义?您可以通过强制转换获得相同的结果。
如果您想要通过十一个不同的结构访问数据(而不是指针),那么在联合中您不想使用指针,而是直接使用结构:
现在是您的
block_payload_union_t
struct 只是 64 位,您可以使用十一个版本中的任何一个来处理此数据。What's the point in having pointers as members in your union? You could achieve the same result via casts.
If what you want is to access the data (and not the pointers) through the eleven different structures, then in the union you don't want to use pointers but the structs directly:
Now the size of your
block_payload_union_t
struct is just 64-bits, and you can work with this data using any of the eleven versions.#pragma pack(1) 指令会导致该成员以 1 字节边界打包在结构中,但是 #pragma pack 指令会对齐结构中的所有位字段/union 在 1 位边界上。这就是最后一场比赛拉开帷幕的原因。检查control_block_format_1_s的sizeof是8还是9。
#pragma pack(1) directive would cause that member to be packed in the structure on a 1-byte boundary, however #pragma pack directive aligns all bit fields in a structure/union on 1-bit boundaries. This is why the last field is kicked off. Check the sizeof of control_block_format_1_s whether it is 8 or 9.