联合内的位填充结构和类型转换

发布于 2024-12-14 14:03:42 字数 3653 浏览 4 评论 0原文

我有一个无符号 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哑剧 2024-12-21 14:03:43

您应该在调用 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):

sizeof(union) = 8
sizeof(cb1) = 8
FDW = 0xFEDCBA9876543210
*bp->llp = 0xFEDCBA9876543210
bp->cb1->block_type_fld = 0x10
bp->cb1->control_word_0 = 0x32
bp->cb1->control_word_1 = 0x28
bp->cb1->control_word_2 = 0x59
bp->cb1->control_word_3 = 0x43
bp->cb1->control_word_4 = 0x29
bp->cb1->control_word_5 = 0x17
bp->cb1->control_word_6 = 0x37
bp->cb1->control_word_7 = 0x7F

Without #pragma pack(1)

sizeof(union) = 8
sizeof(cb1) = 9
FDW = 0xFEDCBA9876543210
*bp->llp = 0xFEDCBA9876543210
bp->cb1->block_type_fld = 0x10
bp->cb1->control_word_0 = 0x32
bp->cb1->control_word_1 = 0x54
bp->cb1->control_word_2 = 0x76
bp->cb1->control_word_3 = 0x18
bp->cb1->control_word_4 = 0x3A
bp->cb1->control_word_5 = 0x5C
bp->cb1->control_word_6 = 0x7E
bp->cb1->control_word_7 = 0x10

你得到什么?

程序

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#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
{
    long long *llp;
    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()

int main(void)
{
    long long final_data_word = 0xFEDCBA9876543210;
    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%.16llX\n", final_data_word);
    printf("*bp->llp = 0x%.16llX\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);
    return(0);
}

You should be using sizeof(block_payload_union_t) instead of sizeof(block_payload_union_t *) in the call to malloc(). 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):

sizeof(union) = 8
sizeof(cb1) = 8
FDW = 0xFEDCBA9876543210
*bp->llp = 0xFEDCBA9876543210
bp->cb1->block_type_fld = 0x10
bp->cb1->control_word_0 = 0x32
bp->cb1->control_word_1 = 0x28
bp->cb1->control_word_2 = 0x59
bp->cb1->control_word_3 = 0x43
bp->cb1->control_word_4 = 0x29
bp->cb1->control_word_5 = 0x17
bp->cb1->control_word_6 = 0x37
bp->cb1->control_word_7 = 0x7F

Without #pragma pack(1):

sizeof(union) = 8
sizeof(cb1) = 9
FDW = 0xFEDCBA9876543210
*bp->llp = 0xFEDCBA9876543210
bp->cb1->block_type_fld = 0x10
bp->cb1->control_word_0 = 0x32
bp->cb1->control_word_1 = 0x54
bp->cb1->control_word_2 = 0x76
bp->cb1->control_word_3 = 0x18
bp->cb1->control_word_4 = 0x3A
bp->cb1->control_word_5 = 0x5C
bp->cb1->control_word_6 = 0x7E
bp->cb1->control_word_7 = 0x10

What are you getting?

Program

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#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
{
    long long *llp;
    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()

int main(void)
{
    long long final_data_word = 0xFEDCBA9876543210;
    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%.16llX\n", final_data_word);
    printf("*bp->llp = 0x%.16llX\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);
    return(0);
}
一身仙ぐ女味 2024-12-21 14:03:43

让指针作为工会成员有什么意义?您可以通过强制转换获得相同的结果。

如果您想要通过十一个不同的结构访问数据(而不是指针),那么在联合中您不想使用指针,而是直接使用结构:

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;

现在是您的 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:

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;

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.

素手挽清风 2024-12-21 14:03:43

#pragma pack(1) 指令会导致该成员以 1 字节边界打包在结构中,但是 #pragma pack 指令会对齐结构中的所有位字段/union 在 1 位边界上。这就是最后一场比赛拉开帷幕的原因。检查control_block_format_1_ssizeof是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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文