在位字段中,如何处理单位(布尔)成员

How are single-bit (boolean) members in bit fields handled?

本文关键字:处理 单位 成员 布尔 何处理 字段      更新时间:2023-10-16

当我请求或设置位 struct/ class的单位成员时,编译器是否有点偏移?例如,给定此struct

struct {
    unsigned char thing : 4;
    unsigned char flag1 : 1;
    unsigned char flag2 : 1;
    unsigned char reserved : 2;
}

...编译器是否意识到不需要位转移?换句话说,编译器会这样做:

uchar request_flag1() const {
    uchar temp = data & 0x40;       //0100 0000 - get the 7th bit
    return temp >> 7;               //0000 0001 - return the shifted value
}
void set_flag1(uchar v) {
    data &= 0x191;                  //1011 1111 - clear the 7th bit
    data |= v << 7;                 //0v00 0000 - set the 7th bit to shifted value
}

或这个?

bool request_flag1() const {
    return data & 0x40;             //0100 0000 - simply check whether the 7th bit is set
}
void set_flag1(bool v) {
    if(v) data |= 0x40;             //0100 0000 - simply set the 7th bit
    else data &= 0x191;             //1011 1111 - simply clear the 7th bit
}

我想,由于操作的数量是一半,因此后者的速度要快得多。

如果后者 true,我是否必须将BIT字段成员声明为类型bool才能获得此优势?

编译器将您的位操作转换为任何一系列的位和/或/不操作以完成工作。

,例如

s.flag1 = 1;

将成为

s = s | 00000010;
        ^^^^^^-----stuff
              ^----flag1
               ^---flag2

和分配的实际值取决于您要编制的特定CPU的位/字节排序。

您的问题通常无法回答。每个编译器都可以自由决定如何实现Bitfield。不能保证它首先是高位或低位。这可能取决于系统的饮食性,但也不能保证。因此,将联合转换用于位场绝对不是便携式的!

编译器可以生成的代码取决于编译器及其必须创建代码的CPU。例如,如果要测试并设置一些设置,则某些CPU体系结构完全支持单个操作码/指令为该使用情况。另一个CPU可能只能检查LSB,因此必须将其移动n次才能捕获所需的位。其他一些CPU可能与A和/或组合一起使用。

简单答案:这取决于: - )

,但是几乎可以保证,现代编译器将尽最大努力生成可以在选定的CPU上完成工作的最小或禁食的代码。

如果您真的想知道编译器生成了什么,只需查看生成的汇编。

在Linux上您可以使用: objdump -S a.out这为您提供了组装和源代码相互混合。