问题描述
我有一个与此question类似的问题。 我想在编译时获得结构的大小,包括所有未添加编译器特定填充的子结构。
-property:Platform
由于我不想包含填充,我希望结构/p:Platform
的大小为18(包括子结构struct Bar {
BOOST_HANA_DEFINE_STRUCT(Bar,(std::uint8_t,a),(std::uint16_t,b)
);
};
struct Foo {
BOOST_HANA_DEFINE_STRUCT(Foo,b),(std::uint32_t,c),(std::uint64_t,d),(Bar,bar)
);
};
template <typename T>
constexpr auto bytesize() -> size_t
{
if constexpr (std::is_arithmetic<T>::value || std::is_enum<T>::value)
return sizeof(T);
else if constexpr (std::is_class<T>::value)
{
return hana::fold_left(
hana::accessors<T>(),[](auto total,auto member) {
// I want to call bytesize recusively here:
return bytesize<decltype(hana::second(member)(std::declval<T>()))>() + total;
});
}
}
static_assert(bytesize<Foo>() == 18);
的大小),但是链接问题中的代码确实在计算中包括填充,我的大小为19。问题在于函数应该在遇到的所有结构上递归调用字节大小。
解决方法
返回的类型不是您期望的类型(附加&&
),您会遇到问题。 std::decay_t
解决了该问题:
return hana::fold_left(
hana::accessors<T>(),[](auto total,auto member) {
using member_type = std::decay_t<decltype(hana::second(member)(std::declval<T>()))>;
constexpr auto member_size = bytesize<member_type>();
return total + member_size;
});
,
结构的尺寸更大,因为存在填充或对齐方式。
https://en.wikipedia.org/wiki/Data_structure_alignment
在gcc
和clang
上,您可以使用__attribute__((__packed__))
struct Bar {
BOOST_HANA_DEFINE_STRUCT(Bar,(std::uint8_t,a),(std::uint16_t,b)
);
} __attribute__((__packed__));
示例
https://godbolt.org/z/odMTEs
请注意,在x86上,压缩结构不会产生负面影响。至少无法测量。
在Arm上,它们也可以“快速运行”。
但是,在其他一些体系结构上,它们可能真的很慢,甚至可能“崩溃” CPU。