有没有一种方法(trait或其他方式),可以检测结构体/类是否有填充?
我不需要跨平台或标准化的解决方案,我只需要针对MSVC2013。
我可以这样检查:
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);
但是C++不允许(据我所知)生成这种非侵入式的代码(不触及现有结构体)。
理想情况下,我希望能够得到像这样工作的代码。
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{};
编辑 - 为什么我需要这个?
我正在使用现有的序列化系统,它将一些结构体(在通用函数内部)存储为void*
,并存储sizeof(T)
字节的数据... 这样的二进制文件在我们所针对的平台上不具备可移植性,因为使用了不同的编译器,所以无法保证插入填充的方式。如果我能静态检测到所有带填充的T
结构体,我就可以强制用户手动插入填充(例如某些控制填充而不是随机垃圾),这样就没有“随机”填充了。另一个好处是,当我比较两个相同场景的保存文件时,它们看起来是一样的。
编辑2 我越想越明白,我需要跨平台的解决方案。我们主要在msvc2013上开发,但我们的应用程序最终会在msvc2012和clang中进行构建。但是,如果我在msvc2013中检测并消除了所有由编译器生成的填充,那么就不能保证其他编译器不会插入填充...(因此,仅检测msvc2013是不够的)。
std::has_unique_object_representations
。请参见编译时检查以确保结构体中没有任何填充。 - phuclv