Is there a way (trait or so) to detect, if struct/class has some padding?
I don't need cross-platform or standardized solution, I need it for MSVC2013.
I can check it like
namespace A
{
struct Foo
{
int a;
bool b;
};
}
#pragma pack(push, 1)
namespace B
{
struct Foo
{
int a;
bool b;
};
}
#pragma pack(pop)
static const bool has_padding = sizeof(A::Foo) != sizeof(B::Foo);
But C++ doesn't allow (as far as I know) generate this non-invasive (without touching existing structs)
Ideally I would like to get working something like this
template <typename T>
struct has_padding_impl
{
typedef __declspec(align(1)) struct T AllignedT;
};
template <typename T>
struct has_padding : typename std::conditional<sizeof(typename has_padding_impl<T>::AllignedT) == sizeof(T),
std::false_type,
std::true_type>::type{};
EDIT - Why do I need this?
I'am working with existing serialization system, which store some struct just taking void*
to them (inside generic function) and store sizeof(T)
number of bytes... Such binary file is not portable on platforms we are targeting, since different compilers are used, so there is no guarantee how is padding inserted. If I could statically detect all T
which are structs with padding, I can force user to manually insert padding (some control padding e.g. not just random garbage) so there is no "random" padding. Another adventage is, when I diff two save files of same scenerio, they will look the same.
edit 2 the more I think about it, the more I realize I need cross-platform solution. We mainly develop on msvc2013 but our application is at final builded in msvc2012 and clang. But if I detected and get rid of all compiler-generated padding in msvc2013, there is no guarantee that other compiler doesn't insert padding... (so msvc2013 detection is not enough)
Do you need this information during run time? Because if you want to know it in build time I believe you can use static_assert to get this information.
struct foo
{
uint64_t x;
uint8_t y;
};
#define EXPECTED_FOO_SIZE (sizeof(uint64_t) + sizeof(uint8_t))
static_assert(sizeof(foo) == EXPECTED_FOO_SIZE, "Using padding!");
If you need it during run time, you can try something like:
static const bool has_padding = (sizeof(foo) != EXPECTED_FOO_SIZE);
Also check this link from earlier post, maybe it will help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With