继承和属性打包
inheritance and attribute packed
在 C++ 中考虑这段代码
struct Base
{
std::int64_t x;
std::int64_t y;
};
static_assert(sizeof(Base) == 16, "Base not of size 16!");
struct Derived : Base
{
std::int32_t z;
}__attribute__((packed));
static_assert(sizeof(Derived) == 20, "Derived not of size 20!");
clang 认为此代码有效,而 gcc 导致触发第二个 static_assert。 (“Derived not of size 20!”)。如果我也添加打包在 Base 中的属性,那么它在两个编译器中都很好。有谁知道哪个是正确的,为什么?
都对。
允许编译器向您的 class 添加填充(在成员之间和末尾)并且它是实现定义的,无论是否这样做,所以您的 static_assert
基本上是在测试取决于所使用的编译器(和平台)的东西 - 因此它们不可移植,你不能期望到处都有相同的结果。
您对 __attribute__((packed))
的使用基本上告诉了解该属性的编译器您想要特定的行为而不是默认情况下的行为。在这种情况下,这可能会生成您想要的结果,但它也有影响(内存 layout/use 和某些 CPU 性能)。而且您仍然不能确定所有编译器都会做同样的事情。
这是一个实现定义的概念,因实现和编译器而异。
如前所述,允许编译器向 class 添加额外的 space,并且您编写的代码不可移植。 space 的数量或添加的填充因编译器而异,并且没有代码可以进行可靠的检查来满足所有要求。这会导致在不同的地方会有不同的结果,因为,所有的编译器都是不同的。
在 C++ 中考虑这段代码
struct Base
{
std::int64_t x;
std::int64_t y;
};
static_assert(sizeof(Base) == 16, "Base not of size 16!");
struct Derived : Base
{
std::int32_t z;
}__attribute__((packed));
static_assert(sizeof(Derived) == 20, "Derived not of size 20!");
clang 认为此代码有效,而 gcc 导致触发第二个 static_assert。 (“Derived not of size 20!”)。如果我也添加打包在 Base 中的属性,那么它在两个编译器中都很好。有谁知道哪个是正确的,为什么?
都对。
允许编译器向您的 class 添加填充(在成员之间和末尾)并且它是实现定义的,无论是否这样做,所以您的 static_assert
基本上是在测试取决于所使用的编译器(和平台)的东西 - 因此它们不可移植,你不能期望到处都有相同的结果。
您对 __attribute__((packed))
的使用基本上告诉了解该属性的编译器您想要特定的行为而不是默认情况下的行为。在这种情况下,这可能会生成您想要的结果,但它也有影响(内存 layout/use 和某些 CPU 性能)。而且您仍然不能确定所有编译器都会做同样的事情。
这是一个实现定义的概念,因实现和编译器而异。
如前所述,允许编译器向 class 添加额外的 space,并且您编写的代码不可移植。 space 的数量或添加的填充因编译器而异,并且没有代码可以进行可靠的检查来满足所有要求。这会导致在不同的地方会有不同的结果,因为,所有的编译器都是不同的。