如何确定/测量具有位字段的结构的大小?

发布于 2024-10-02 02:10:49 字数 415 浏览 4 评论 0原文

#include <stdio.h>

typedef struct size
{
        unsigned int a:1;
        unsigned int b:31;
        unsigned int c:1;
} mystruct;

int main()
{
        mystruct a;
        printf("%d", sizeof(a));
        return 0;
}
  • 使用 int b:31 时,输出为 8。
  • 使用 int b:1 时,输出为 4。
  • 使用 int b:32 时,输出 为输出是 12。

有人能解释一下原因吗?

#include <stdio.h>

typedef struct size
{
        unsigned int a:1;
        unsigned int b:31;
        unsigned int c:1;
} mystruct;

int main()
{
        mystruct a;
        printf("%d", sizeof(a));
        return 0;
}
  • With int b:31, the output is 8.
  • With int b:1, the output is 4.
  • With int b:32, the output is 12.

Can somebody explain the reason for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南风几经秋 2024-10-09 02:10:49

重要的是顺序。以下代码将给出输出: 8

#include<stdio.h>

typedef struct size
{
        unsigned int b:32;
        unsigned int a:1;
        unsigned int c:1;
}mystruct;

int main(int argc, char const *argv[])
{
        mystruct a;
        printf("\n %lu \n",sizeof(a));
        return 0;
}

Unsigned int 是一个 32 位整数,占用 4 个字节。内存在内存中是连续分配的。


选项 1:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:31;      // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Second 4 bytes are allocated

输出:8


选项 2:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:32;      // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated
unsigned int c:1;       // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated

输出:12


选项 3:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:1;       // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Will get accomodated in the First 4 bytes

输出:4


选项 4:

unsigned int b:32;      // First 4 bytes are allocated
unsigned int a:1;       // Second 4 bytes are allocated
unsigned int c:1;       // Will get accomodated in the Second 4 bytes

输出:8

It is the order that matters. The following code will give Output: 8

#include<stdio.h>

typedef struct size
{
        unsigned int b:32;
        unsigned int a:1;
        unsigned int c:1;
}mystruct;

int main(int argc, char const *argv[])
{
        mystruct a;
        printf("\n %lu \n",sizeof(a));
        return 0;
}

Unsigned int is a 32 bit integer, occupying 4 bytes. Memory is allocated contiguously in memory.


Option 1:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:31;      // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Second 4 bytes are allocated

Output: 8


Option 2:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:32;      // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated
unsigned int c:1;       // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated

Output: 12


Option 3:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:1;       // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Will get accomodated in the First 4 bytes

Output: 4


Option 4:

unsigned int b:32;      // First 4 bytes are allocated
unsigned int a:1;       // Second 4 bytes are allocated
unsigned int c:1;       // Will get accomodated in the Second 4 bytes

Output: 8

哭泣的笑容 2024-10-09 02:10:49

您没有说您是否知道位域是什么,但我假设您知道。

在你的实现中,显然unsigned int是一个32位整数,占用4个字节。这说明了第一个和第二个示例。显然,总共 33 位的 3 个位域不适合单个 unsigned int,因此第一个示例中需要 8 个字节。总共 3 位的 3 个位域确实适合一个 unsigned int,因此第二个示例中只有 4 个字节。

此外,位域不能跨越多个整数。这就是第三个例子。我不记得这是标准的要求,还是只是实施的细节。无论哪种方式,由于 b 是 32 位,它会自行填充整个 unsigned int,从而强制 ac< /code> 占据自己的unsigned int,前后中间一个。因此,为 12 个字节。

You don't say whether you know what bitfields are, but I'll assume you do.

On your implementation, evidently unsigned int is a 32 bit integer, occupying 4 bytes. This accounts for the first and second examples. Clearly 3 bitfields totalling 33 bits don't fit into a single unsigned int, hence the need for 8 bytes in the first example. 3 bitfields totalling 3 bits certainly do fit into an unsigned int, hence only 4 bytes in the second example.

Furthermore, a bitfield cannot span multiple integers. This accounts for the third example. I can't remember whether that's a requirement of the standard, or just a detail of your implementation. Either way, since b is 32 bits, it fills a whole unsigned int on its own, forcing both of a and c to occupy their own unsigned int, before and after the middle one. Hence, 12 bytes.

無心 2024-10-09 02:10:49

根据史蒂夫·杰索普的回答只是为了通过添加一些可能有帮助的文档来完成他的回答。

结构或联合的成员可以具有除可变修改类型之外的任何完整对象类型。此外,可以将成员声明为由指定数量的位组成(包括符号位,如果有的话)。这样的成员称为位域,其宽度前面带有冒号

实现可以分配任何足够大的可寻址存储单元来容纳位字段。 如果剩余足够的空间,则结构中紧随另一个位字段的位字段应打包到同一单元的相邻位中。如果剩余空间不足,则将不适合的位域放入下一个单元或与相邻单元重叠是实现定义的。单元内位域的分配顺序(从高位到低位) -阶或低阶到高阶)是实现定义的。可寻址存储单元的对齐方式未指定。

在结构体对象中,非位域成员和位域所在的单元的地址按照声明的顺序递增。指向结构对象的指针经过适当转换后,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象内可能有未命名的填充,但不是在其开头。

——ISO/IEC 9899:201x 6.7.2.1

According to Steve jessop's answer just to fulfill his answer by adding some documents which may help.

A member of a structure or union may have any complete object type other than a variably modified type.In addition, a member may be declared to consist of a specified number of bits (including a sign bit, if any). Such a member is called a bit-field its width is preceded by a colon

An implementation may allocate any addressable storage unit large enough to hold a bit- field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

——ISO/IEC 9899:201x 6.7.2.1

哥,最终变帅啦 2024-10-09 02:10:49

对齐

编译器将结构的大小舍入为 32 位,它可能尝试引用 32 位的每个对象的大小,同时它保留位字段的顺序。

因此,如果中间有一个 32 位项目,每一侧都有 1 位项目,则需要分配 3 个 32 位字,因此:12 个字节。

对于其他两种情况,问题只是您的位域序列可以打包到多少个 32 位对象中,同时仍保留字段顺序。

Alignment

The compiler is rounding the size of the structure to 32 bits, the size of each object it may try to reference to 32 bits, and at the same time it is preserving the order of your bit fields.

So if you have a 32-bit item in the middle and 1-bit items on each side, that's 3 32-bit words to allocate and so: 12 bytes.

For the other two cases, it's just a question of how few 32-bit objects your bitfield sequence can be packed into, while still preserving field order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文