Reputation: 360
I have a similar Problem as in this question. I want to get the size of struct at compile time, including all the substructs without the compiler specific padding added.
struct Bar {
BOOST_HANA_DEFINE_STRUCT(Bar,
(std::uint8_t, a),
(std::uint16_t, b)
);
};
struct Foo {
BOOST_HANA_DEFINE_STRUCT(Foo,
(std::uint8_t, a),
(std::uint16_t, 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>(), 0, [](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);
As I don't want to include the padding, I expect the size of the struct Foo
to be 18 (including the size of the substruct Bar
) but the code in the linked question does include the padding in the calculation and gives me a size of 19. The problem lies therein that the function should call bytesize recursively on all structs it encounters.
A minimal example which does not work as intended can be found here.
Upvotes: 1
Views: 176
Reputation: 218098
You have issue with returned types which are not what you expect (extra &&
). std::decay_t
fixes the issue:
return hana::fold_left(
hana::accessors<T>(), 0, [](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;
});
Upvotes: 2
Reputation: 10539
Size of the structure is more, because there is padding or alignment.
https://en.wikipedia.org/wiki/Data_structure_alignment
On gcc
and clang
you can use __attribute__((__packed__))
struct Bar {
BOOST_HANA_DEFINE_STRUCT(Bar,
(std::uint8_t, a),
(std::uint16_t, b)
);
} __attribute__((__packed__));
Example
https://godbolt.org/z/odMTEs
Note, on x86, packed structs does NOT have negative effect. Not measurable at least.
On Arm they also work "fast enought".
However on some other architectures they might be really slow or even they can "crash" the CPU.
Upvotes: 0