【问题标题】:Is it possible and correct to form union from bit-field in C?从C中的位域形成联合是否可能且正确?
【发布时间】:2014-03-20 11:04:05
【问题描述】:

我有以下联合,它工作正常:

#pragma pack(1)
...
union
{
    uint8_t opcode;
    struct
    {
        uint8_t z : 3;
        uint8_t y : 3;
        uint8_t x : 2;
    };
}opcode;    

联合的大小正好是一个字节,根据

printf ("%zu\n", sizeof opcode);  

当我尝试从那里的位域进行联合时出现问题:

union
{
    uint8_t opcode;
    struct
    {
        uint8_t z : 3;
        union
        {
            uint8_t y : 3;
            struct
            {
                uint8_t p : 2;
                uint8_t q : 1;
            };
        }y;
        uint8_t x : 2;
    };
}opcode;    

结果

printf ("%zu\n", sizeof opcode);  

是 3 个字节。当然我可以用宏来解决这个问题,但这有可能吗?

【问题讨论】:

    标签: c unions bit-fields


    【解决方案1】:

    您的代码将声明一个 3 字节的数据结构,因为正如 Klas 已经指出的那样,结构总是填充到最小的可寻址单元。

    但是可以通过在联合中嵌入多个顶级结构并在必要时添加填充来做你想做的事情:

    union {
        uint8_t opcode;
        struct {
            uint8_t z:3;
            uint8_t y:3;
            uint8_t x:2;
        };
        struct {
            uint8_t:3;
            uint8_t p:2;
            uint8_t q:1;
        };
    } opcode;
    

    请注意,可以声明没有填充名称的位域。这是标准的 C 语言功能。

    【讨论】:

    • 太完美了!非常优雅的解决方案。非常感谢!
    【解决方案2】:

    不,不可能有一个字节大小的结构。

    理由:

    必须可以做一个指向结构体的指针,最小可寻址单位是1字节。

    注意: 这个限制存在于我知道的所有编译器中。我不知道它是否实际上是由 C 标准规定的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多