有没有办法让 union "over-compensate" 对齐?
Is there a way to not have a union "over-compensate" alignment?
我的结构如下所示:
class Foo {
union {
size_t cap;
char buff[15];
};
bool isHeap;
};
我希望 sizeof(Foo)
等于 16
,但 sizeof(Foo)
在 64 位计算机上是 24
。我认为这是因为 size_t
强制联合的对齐方式为 8
,因此在 buff
之后有 1
浪费字节,在 [ 之后有 7
=22=]。我想到了这个解决方案:
class Foo {
union{
struct {
size_t cap;
char ignore[7];
bool isHeap1;
};
struct {
char buff[15];
bool isHeap2
};
};
};
但它依赖于未定义的行为,因为您不知道是否要检查 isHeap1
或 isHeap2
,直到您已经访问了它们的值之一。
有没有办法不浪费那些不依赖未定义行为的字节?
作为旁注,我想不出这个问题的真正好名字,如果有人能想到一个更好的名字那就太好了。如果有人建议更好的名字,或者如果你们认为它已经是一个合理的名字,我会删除这条评论。
您可以将 packed
属性添加到 union 以强制它为 15 个字节,然后包含 class 将是 16 个字节:
class Foo {
union __attribute__((packed)) {
size_t cap;
char buff[15];
};
bool isHeap;
};
struct {
size_t cap;
char ignore[7];
bool isHeap1;
};
C++ 没有匿名结构。这是 C++ 中的 ill-formed。
But it relies on undefined behavior as you don't know whether to check isHeap1 or isHeap2 until you have already accessed one of their values.
如果成员的顺序是灵活的,那么这将是一个定义明确的替代方案:
union {
struct {
bool isHeap;
size_t cap;
} s1;
struct {
bool isHeap;
char buff[15];
} s2;
};
这是允许访问联合体的非活动成员的特殊情况:两个标准布局结构的公共初始序列。换句话说,即使 s1
是活动成员,阅读 s2.isHeap
也是明确定义的,并且会导致 s1.isHeap
和 vice-versa 的值。
我的结构如下所示:
class Foo {
union {
size_t cap;
char buff[15];
};
bool isHeap;
};
我希望 sizeof(Foo)
等于 16
,但 sizeof(Foo)
在 64 位计算机上是 24
。我认为这是因为 size_t
强制联合的对齐方式为 8
,因此在 buff
之后有 1
浪费字节,在 [ 之后有 7
=22=]。我想到了这个解决方案:
class Foo {
union{
struct {
size_t cap;
char ignore[7];
bool isHeap1;
};
struct {
char buff[15];
bool isHeap2
};
};
};
但它依赖于未定义的行为,因为您不知道是否要检查 isHeap1
或 isHeap2
,直到您已经访问了它们的值之一。
有没有办法不浪费那些不依赖未定义行为的字节?
作为旁注,我想不出这个问题的真正好名字,如果有人能想到一个更好的名字那就太好了。如果有人建议更好的名字,或者如果你们认为它已经是一个合理的名字,我会删除这条评论。
您可以将 packed
属性添加到 union 以强制它为 15 个字节,然后包含 class 将是 16 个字节:
class Foo {
union __attribute__((packed)) {
size_t cap;
char buff[15];
};
bool isHeap;
};
struct { size_t cap; char ignore[7]; bool isHeap1; };
C++ 没有匿名结构。这是 C++ 中的 ill-formed。
But it relies on undefined behavior as you don't know whether to check isHeap1 or isHeap2 until you have already accessed one of their values.
如果成员的顺序是灵活的,那么这将是一个定义明确的替代方案:
union {
struct {
bool isHeap;
size_t cap;
} s1;
struct {
bool isHeap;
char buff[15];
} s2;
};
这是允许访问联合体的非活动成员的特殊情况:两个标准布局结构的公共初始序列。换句话说,即使 s1
是活动成员,阅读 s2.isHeap
也是明确定义的,并且会导致 s1.isHeap
和 vice-versa 的值。