【问题标题】:Using struct with bitfields inside a struct with bitfields?在带有位域的结构中使用带有位域的结构?
【发布时间】:2020-09-01 18:40:06
【问题描述】:

让我们看看下面的structs

struct child {
    int a:1;
    int b:2;
    int c:2;
} __attribute__((packed));

struct parent1 {
    int x:3;
    struct child y;
} __attribute__((packed));

struct parent2 {
    int p:1;
    int q:5;
    int r:5;
    struct child s;
} __attribute__((packed));

这些是我得到的尺寸:

sizeof(int)             4
sizeof(struct child)    1
sizeof(struct parent1)  2
sizeof(struct parent2)  3

我听说出于性能原因在结构之前添加了填充。 但是暂时忘记了性能, 有没有办法让我得到以下尺寸?

sizeof(struct parent1)  1
sizeof(struct parent2)  2

实际上只需要这么多内存...


编辑

linux 上使用gcc 有什么办法吗?

【问题讨论】:

标签: c memory struct bit-fields


【解决方案1】:

不,不可能将结构打包得比编译器所做的更紧密。

每个结构都必须以字节边界开始,因此成员 sy 不能使用其封闭结构定义的先前成员中的可用位。

另请注意,__attribute__((packed)) 是许多编译器可能不支持的扩展。

【讨论】:

    【解决方案2】:

    如果所有其他方法都失败了,您始终可以编写函数和宏来移位并提取您需要的内容。

    使用联合可以接近您想要的。可以使用 C++ 来清理语法,但是使用 C,这是我能想到的最接近(非按位)的解决方案: (注意 parent1 接近完美。)

    #pragma pack(1)
    typedef struct {
      char x:3;
      char a:3;
      char b:3;
      char c:3;
    } child;
    
    typedef union {
      char x:3;
      child y;
    } parent1;
    
    typedef struct {
      short p:1;
      short q:5;
      short r:5;
      short s:5;
    } par2;
    
    typedef struct {
      char pad;
      child s;
    } padchild;
    
    typedef union {
      par2 parent2;
      padchild s;
    } parent2;
    
    #pragma pop
    

    从技术上讲,联合用于非此即彼的使用,编译器可以随意填充,但是通过强制位数相同,编译器实现的最简单方法恰好是您想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      相关资源
      最近更新 更多