代码之家  ›  专栏  ›  技术社区  ›  Rm02

位字段和联合的有效使用

  •  0
  • Rm02  · 技术社区  · 6 年前

    我写这段代码只是为了好玩:

    union {
        struct {
            bool a : 1;
            bool b : 1;
            bool c : 1;
            bool d : 1;
            bool e : 1;
            bool f : 1;
            bool g : 1;
            bool h : 1;
        } a;
        uint8_t b;
    } uni {0}; // sets .a bits to false
    
    // union size  : 1 byte
    

    我可以单独切换每个位:

    uni.a.a = true;
    uni.a.d = true;
    
    cout << bitset<8>(uni.b) << endl; // Prints 000010001
    

    并使用位掩码:

    uni.b = 0b00001000;
    
    if(uni.a.a) cout << "a";
    if(uni.a.b) cout << "b";
    if(uni.a.c) cout << "c";
    if(uni.a.d) cout << "d";
    if(uni.a.e) cout << "e";
    if(uni.a.f) cout << "f";
    if(uni.a.g) cout << "g";
    if(uni.a.h) cout << "h";
    // prints 'd'
    

    我知道还有其他方法可以做到这一点(按位操作),但我喜欢这种设计。我的问题是: 就可靠性和性能而言,这是对位字段和联合的良好使用吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Daniel    6 年前

    我的问题是:就可靠性和性能而言,这是对位字段和联合的良好使用吗?

    就性能而言,您所做的可能与它将获得的一样好,至少在位级别访问内存方面是如此。

    就可靠性而言,在大多数现代系统中,这可能是可行的。冒着听起来像语言律师的风险,以下是一些可能在不同系统中产生不同结果的领域:

    1. sizeof(bool) 也就是说,不能保证为1 bool 可以存储在大于一个字节的内存中。我不知道任何现代系统 布尔 不是字节大小,但您可以想象一个旧的或糟糕的实现 布尔 int . 这会让你的 union
    2. 访问的不同成员变量 协会 can导致的未定义行为
    3. 系统之间的字节顺序可能不同(例如,大端或小端),导致 协会 将表示MSB。
    4. 从技术上讲,该实现可以在一个字节内按任何顺序排列位字段的各个位。我知道的每个实现都会按照您在 struct ,但这不是必须的。
    5. 实现可以在 结构 这样,各个位在不同的内存字节中。同样,我所知道的所有实现都不会做到这一点,但这是可能发生的。

    我认为你不必担心上述问题。但是,就涵盖所有可能出错的方面而言,我认为上面的列表很好地涵盖了如果您真的搜索一个稍微不同的实现,您可能会面临的非常奇怪的情况。