gpt4 book ai didi

具有位字段的结构的 C++ 大小

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:27:39 24 4
gpt4 key购买 nike

我有以下三个 union :

typedef union {
struct {
uint16_t : 2;
uint16_t numberOfWords : 10;
uint16_t : 4;
uint16_t dataFormat : 8;
uint16_t : 8;
} bf;
uint32_t dw;
} HeaderT;

typedef union {
struct {
uint16_t : 4;
uint16_t lsb : 8;
uint16_t : 4;
uint16_t msb : 8;
uint16_t : 8;
} bf;
uint32_t dw;
} RegisterT;

typedef union {
struct {
uint16_t : 2;
uint16_t lsb : 10;
uint16_t : 2;
uint16_t msb : 10;
uint16_t : 8;
} bf;
uint32_t dw;
} BinT;

我得到 sizeof(HeaderT) == 4,sizeof(RegisterT) == 4,但是 sizeof(BinT) == 8!我也不知道为什么。

typedef union {
struct {
uint16_t : 2;
uint16_t lsb : 10;
uint16_t : 2;
uint16_t msb : 10;
uint16_t : 8;
} bf __attribute__((packed));
uint32_t dw;
} BinT;

没有帮助。我需要 BinT 为 32 位宽;它被内存映射到 FPGA 上的一堆寄存器。

有人知道这是怎么回事吗?我在 ARMv7 上使用 gcc。但是,我在 x86_64 VirtualBox VM 上的 gcc 上看到了同样的情况。

谢谢。

最佳答案

位域成员不能拆分为两个(或更多)原语。好吧,就标准而言,根本无法保证包装。它是实现定义的。但这是一个典型的限制,如果实现确实打包了位字段的话。

让我们看看 GCC manual 是什么说到实现定义的行为:

  • 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.

我不确定这是否适用于 ARM,但通常 GCC 符合 64-bit Itanium spec .

(假设从左到右打包)你的基元之间的“位分布”现在是:

uint16_t: 2 10 2 // 10 won't fit anymore
uint16_t: 10 // 8 won't fit anymore
uint16_t: 8

这三个 uint16_t 不可能适合 32 位。

这个:

union BinT {
struct {
uint32_t : 2;
uint32_t lsb : 10;
uint32_t : 2;
uint32_t msb : 10;
uint32_t : 8;
} bf;
uint32_t dw;
};

应该可以工作,因为现在所有位字段都可以共享一个原语。

OK, so by changing the uint16_t's throughout to unsigned I get the expected result. I don't understand why, though

unsigned 将显示为 32 位宽。

I need BinT to be 32-bits wide

鉴于该要求,如果您希望程序可移植,您可能应该避免使用位字段。如果您使用位字段,则取决于实现定义的行为。

关于具有位字段的结构的 C++ 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35056179/

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