【发布时间】:2017-12-08 08:45:05
【问题描述】:
我有一个继承自 struct Base 的 struct X。但是,在我当前的设置中,由于对齐,X 的大小为 24B:
typedef struct {
double_t a;
int8_t b;
} Base;
typedef struct {
Base base;
int8_t c;
} X;
为了节省内存,我想展开 Base 结构,所以我创建了包含来自 Base 的字段的结构 Y(以相同的顺序,总是在结构的开头),所以结构为 16B:
typedef struct {
double_t base_a;
int8_t base_b;
int8_t c;
} Y;
然后我将在一个方法中使用 struct Y 的实例,该方法需要一个指向 Base struct 的指针:
void print_base(Base* b)
{
printf("%f %d\n", b->a, b->b);
}
// ...
Y data;
print_base((Base*)&data);
上面的代码是否违反了严格的别名规则,导致了未定义的行为?
【问题讨论】:
-
对,修复了示例代码
-
为什么不简单地在
Y中声明Base base;并用print_base(&data.base);调用函数呢?它消耗的内存与其他结构中的结构成员相同。 -
@mch 它没有。使用您的方法的 struct X 的大小需要 24 个字节,而 struct Y 只需 16
-
在我看来,整个 X 类型在这个例子中是无关紧要的。您正在从 Y 投射到与 X 无关的 Base。
-
@Marian 我想介绍正确的方法,并解释为什么我不想这样做。
标签: c inheritance struct strict-aliasing