3

I am implementing a radio standard and have hit a problem with unions in structure and memory size. In the below example I need this structure to located in a single byte of memory (as per the radio standard) but its currently giving me a size of 2 bytes. After much digging I understand that its because the Union's "size" is byte rather than 3 bits...but havent worked out a way around this. I have looked at:

But neither seem to give me a solution.

Any ideas?

Thanks!

#ifdef WIN32
#pragma pack(push)
#pragma pack(1)
#endif

typedef struct three_bit_struct
{
    unsigned char bit_a : 1;
    unsigned char bit_b : 1;
    unsigned char bit_c : 1;
}three_bit_struct_T;


typedef union
{
    three_bit_struct_T three_bit_struct;
    unsigned char another_three_bits : 3;
}weird_union_T;


typedef struct
{
    weird_union_T problem_union; 
    unsigned char another_bit : 1;
    unsigned char reserved : 4;
}my_structure_T;


int _tmain(int argc, _TCHAR* argv[])
{
     int size;

     size = sizeof(my_structure_T);

     return 0;
}


#ifdef WIN32
#pragma pack(pop)
#endif
4

2 回答 2

6

问题是 的大小three_bit_struct_T将被四舍五入到最接近的字节*而不管它在其位域中仅包含三位这一事实。一个结构根本不能有一个字节的一部分的大小。因此,当您使用 中的额外字段对其进行扩充时my_structure_T,大小不可避免地会溢出到第二个字节中。

要将所有这些东西塞进一个字节中,您必须将所有位域成员放在外部,my_structure_T而不是将它们作为内部结构/联合。

我认为你能做的最好的事情就是将整个事情作为一个工会。

typedef struct
{
    unsigned char bit_a : 1;
    unsigned char bit_b : 1;
    unsigned char bit_c : 1;
    unsigned char another_bit : 1;
    unsigned char reserved : 4;
} three_bit_struct_T;

typedef struct
{
    unsigned char another_three_bits : 3;
    unsigned char another_bit : 1;
    unsigned char reserved : 4;
} another_three_bit_struct_T;

typedef union
{
    three_bit_struct_T three_bit_struct;
    another_three_bit_struct_T another_three_bit_struct;
} my_union_T;

(*) 或单词,取决于对齐/包装设置。

于 2012-11-21T12:22:54.567 回答
0

两个好建议:永远不要将 struct/union 用于数据协议,并且永远不要在任何情况下使用位域。

实现这一点的最佳方法是通过位掩码和按位运算符。

#define BYTE_BIT7 0x80u

uint8_t byte;

byte |= BYTE_BIT_7;  // set bit to 1
byte &= ~BYTE_BIT_7; // set bit to 0

if(byte & BYTE_BIT_7) // check bit value

此代码可移植到世界上的每个 C 编译器,也可移植到 C++。

于 2012-11-21T12:48:38.930 回答