在带位域的结构中使用带位域的结构?

时间:2020-05-15 20:18:11

标签: c memory struct bit-fields

让我们看一下以下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

实际上只需要那么多的内存...


编辑

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

2 个答案:

答案 0 :(得分:0)

否,不可能将结构压缩得比编译器更紧密。

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

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

答案 1 :(得分:0)

如果其他所有方法均失败,则始终可以编写函数和宏以进行位移位并提取所需的内容。

使用工会接近您想要的。可能可以使用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

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

相关问题