我需要创建一个具有位域的结构来封装一些来自硬件的数据。假设我使用特定于编译器的机制来执行打包和排序,则可以创建类似于以下内容的结构(语法上不正确):

typedef struct _BYTE_OF_DATA
{
    uint8_t Reserved1 : 2;
    struct
    {
        uint8_t BitWithSomeMeaning : 1;
        uint8_t BitWithSomeOtherMeaning : 1;
    } BitsWithMeaning;
    uint8_t Reserved2 : 4;
} BYTE_OF_DATA, *PBYTE_OF_DATA;

static_assert(sizeof(BYTE_OF_DATA) == 1, "Incorrect size");

然后可以按以下方式访问它:
BYTE_OF_DATA byteOfData;

byteOfData.Reserved1 = 1;
byteOfData.BitsWithMeaning.BitWithSomeOtherMeaning = 0;

我上面描述的确切方案不起作用,因为我猜struct BitsWithMeaning需要从字节边界开始。我想知道是否还有其他技巧可以实现位域的“嵌套”。

最佳答案

要详细说明我先前的评论,应遵循这些思路进行操作,以允许您使用所需的访问方式。尽管与优雅的方式相去甚远:

typedef union _BYTE_OF_DATA {
    struct {
        uint8_t Reserved1 : 2;
        uint8_t : 2;
        uint8_t Reserved2 : 4;
    };
    struct {
        uint8_t : 2;
        uint8_t BitWithSomeMeaning : 1;
        uint8_t BitWithSomeOtherMeaning : 1;
        uint8_t : 4;
    } BitsWithMeaning;
} BYTE_OF_DATA, *PBYTE_OF_DATA;

我个人更希望使用传统的字段掩码和位置常量,并手动修改寄存器。我的经验是,以这种方式访问​​ volatile I/O位域始终会导致效率低下和易于竞争的代码。

关于c++ - C/C++中的嵌套位域,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29171768/

10-11 20:29