如果struct / class有一些填充,是否有一种方法(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
,我可以强制用户手动插入填充(一些控制填充,例如不仅仅是随机垃圾),因此没有&#34;随机&#34;填充。另一个优点是,当我对同一个scenerio的两个保存文件进行差异化时,它们看起来是一样的。
编辑2 我越是想到它,我就越意识到我需要跨平台的解决方案。我们主要在msvc2013上开发,但我们的应用程序最终在msvc2012和clang中构建。但是,如果我在msvc2013中检测到并删除了所有编译器生成的填充,则无法保证其他编译器不会插入填充...(因此msvc2013检测不够)
答案 0 :(得分:2)
您是否在运行时需要此信息? 因为如果您想在构建时间内了解它,我相信您可以使用static_assert来获取此信息。
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!");
如果您在运行时需要它,可以尝试以下方法:
static const bool has_padding = (sizeof(foo) != EXPECTED_FOO_SIZE);
同时从之前的帖子中查看此link,也许会有所帮助。
答案 1 :(得分:0)
试试这个宏:
#define TO_STR(str) #str
#define DECL_STRUCT_TEST_ALIGNED(structName, test_alignment, body) \
_Pragma(TO_STR(pack(push,test_alignment)))\
struct test_##structName \
body ; \
_Pragma(TO_STR(pack(pop))) \
struct structName \
body; \
static const bool has_padding_##structName = sizeof(test_##structName)!=sizeof(structName);
DECL_STRUCT_TEST_ALIGNED(bar, 1,
{
int a;
bool b;
}
)
DECL_STRUCT_TEST_ALIGNED(foo,1,
{
int a;
int b;
})
现在,您可以在运行时测试:
if (has_padding_foo)
{
printf("foo has padding\n");
} else {
printf("foo doesn't have padding\n");
}
if (has_padding_bar)
{
printf("bar has padding\n");
} else {
printf("bar has no padding\n");
}
而且,如果你想在编译时遇到错误,可以使用static_assert。
答案 2 :(得分:-1)
可能你应该尝试这样的事情:
#include <iostream>
using namespace std;
struct A
{
int a;
bool b;
};
int main(int argc, char *argv[])
{
A foo;
cout << "sizeof struct = " << sizeof(A) << endl;
cout << "sizeof items = " << sizeof(foo.a) + sizeof(foo.b) << endl;
return 0;
}
我得到了:
sizeof struct = 8
sizeof items = 5
我在Ubuntu 14.04上。