gpt4 book ai didi

c++ - 位域是对齐数据的一种方式吗?

转载 作者:行者123 更新时间:2023-12-01 15:12:28 25 4
gpt4 key购买 nike

cppreference

#include <iostream>
struct S {
// will usually occupy 2 bytes:
// 3 bits: value of b1
// 2 bits: unused
// 6 bits: value of b2
// 2 bits: value of b3
// 3 bits: unused
unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;
};
int main()
{
std::cout << sizeof(S) << '\n'; // usually prints 2
}
为什么2位未使用?
不能只是:
unsigned char b1 : 3, b2 : 6, b3 : 2;
这是一种填充方法吗?
谁能解释一下这个位字段是否真的改变了变量的大小,或者它们仅仅是编译器的“建议”? (作为 inline关键字)。如果位字段按照我的理解工作,您将可以在1位上存储一个 bool(boolean) 值(这是不可能的,因为内存被拆分为1个字节的块)

最佳答案

您引用的示例用于说明通常(不一定)将多个位域打包在一起。如果您仔细看一下:

    // 3 bits: value of b1      - 3 bits occupied
// 2 bits: unused - 2 bits left unused
// 6 bits: value of b2 - 6 bits occupied (these 6 can't fit into the previous byte
as 5 bits are already occupied. What will happen in this
case? Will these 6 bits go into the next byte? Will they
somehow *overlap* two bytes?
// 2 bits: value of b3
// 3 bits: unused
如果 sizeof(S) == 2的结果为true,那么我们可以说 b2字段跨越字节。这个例子试图解释这个概念。
该示例在解释这一点时并不太清楚,因此让我创建一个更好的示例:
struct S {
unsigned char b1 : 3, : 2, b2 : 6, b3 : 3;
};
区别是 b3现在是3位。 struct = 3 + 2 + 6 + 3 = 14的总位。如果现在打印 sizeof (S),我将得到 3作为输出,它告诉我系统上没有字节跨越。
此外,您可以在页面底部找到它:
  • Everything about the actual allocation details of bit fields within the class object
    • For example, on some platforms, bit fields don't straddle bytes, on others they do
    • Also, on some platforms, bit fields are packed left-to-right, on others right-to-left


Could anyone explain me if (if I am not wrong) this bit fields actually change the size of the variable or they are just a "suggestion" for the compiler? (as inline keyword). If bit fields works as I understand, you would be able to stor a boolean on 1 bit (which is not possible because the memory is splitted on chunks of 1 bytes)


关于位域的几乎所有内容都是由实现定义的,因此要获得正确的答案,您必须查看每个编译器的文档并阅读ABI文档以获取答案。例如,这来自 GCC docs:

Whether a bit-field can straddle a storage-unit boundary (C90 6.5.2.1, C99 and C11 6.7.2.1).
Determined by ABI.


如果我们查看 assembly generated for GCC 10.1,我们可以看到位域实际上正在被使用:
        # b1: 1, b2: 61, b3: 3

sub rsp, 24
mov eax, -767
lea rdi, [rsp+14]
mov WORD PTR [rsp+14], ax
二进制数 -767:
b3  b6    b1
11 111101 00000001

boolean on 1 bit


如果不提及尝试执行此操作的 std::vector<bool>,答案将是不完整的,但事实证明这并不是一个好主意。

关于c++ - 位域是对齐数据的一种方式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63176408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com