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.
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_tcontains 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