检测struct是否有填充

rel*_*xxx 10 c++ padding type-traits visual-c++

如果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);
Run Code Online (Sandbox Code Playgroud)

但是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{};
Run Code Online (Sandbox Code Playgroud)

编辑 - 为什么我需要这个?

我正在使用现有的序列化系统,它存储一些结构只需要void*它们(在通用函数内)和存储sizeof(T)字节数......这样的二进制文件在我们所针对的平台上是不可移植的,因为使用了不同的编译器,所以那里不保证如何插入填充.如果我可以静态检测所有T带有填充的结构,我可以强制用户手动插入填充(一些控制填充,例如不仅仅是随机垃圾),因此没有"随机"填充.另一个优点是,当我对两个相同scenerio的保存文件进行差异化时,它们看起来是一样的.

编辑2 我想的越多,我就越意识到我需要跨平台的解决方案.我们主要在msvc2013上开发,但我们的应用程序最终在msvc2012和clang中构建.但是,如果我在msvc2013中检测到并删除了所有编译器生成的填充,则无法保证其他编译器不插入填充...(因此msvc2013检测不够)

Ric*_*lev -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;
}
Run Code Online (Sandbox Code Playgroud)

我有:

sizeof struct = 8
sizeof items  = 5
Run Code Online (Sandbox Code Playgroud)

我使用的是 Ubuntu 14.04。