0
typedef struct { int a : 1; } STRA;
typedef struct { STRA stra; int b : 1; } STRB;

Size of STRA is 4 bytes, and size of STRB is 8 bytes.

typedef struct { int a : 1; } STRA;
typedef struct { int a : 1; int b : 1; } STRB;

Size of STRA is 4 bytes, and size of STRB is 4 bytes.

Can I make STRB 4 bytes while still using STRA inside it?

4

2 回答 2

0

不,这是不可能的。当STRB包含 type 的成员时STRA,该成员必须可用作自己的对象。因此,即使STRA包含足够大以包含更多成员的填充,STRB也不能以这种方式使用。那些其他成员将不得不使用不与STRA成员重叠的空间。

要了解原因,请考虑如下代码:

void update(STRA *p) {
    static STRA new = { 1 };
    *p = new;
}

STRB sb;

void foo(void) {
    sb.b = 1;
    update(&sb.stra);
    printf("%d\n", sb.b);
}

update通常通过将 的所有 4 个字节(new包括填充)复制到 中来完成in 的分配*p。如果其中一些空间用于sb.b,它将被覆盖,并且foo()不会1按预期输出。

我猜你可能有一个实现,其中结构的分配一个接一个地复制字段,只留下填充;但这会效率低得多,并且对于填充实际上不包含任何感兴趣的东西的正常情况来说是浪费时间。

这也说明了为什么不能采用其他方式并存储sb.stra在 ; 的填充中STRB。该对象sb.stra需要有自己的地址才能使这段代码工作,并且它需要有一个完整的 4 个字节大小,以便函数update()可以安全地写入所有 4 个字节。

于 2020-12-25T00:54:06.227 回答
-1

这似乎适用于gcc. 我的眼睛不习惯摆弄。您应该决定代码是否回答了您的问题:

#include <stdio.h>

#pragma pack(push, 1)

typedef struct a {
    int v : 1;
}a;

#pragma pack(pop)

typedef struct b {
    a   a_value;
    int b_value : 1;
}b;


int main()
{
    b variable;
 
    printf("%lu %lu %lu\n", sizeof(a), sizeof(b), sizeof(variable.a_value));

    variable.a_value.v = ~0;
    variable.b_value   = ~0;

    printf("0x%04x\n", *(unsigned*)&variable);

    return 0;
}

输出是: 1 4 1 0x0101

于 2020-12-24T22:39:48.217 回答