检测结构是否有填充 [英] Detect if struct has padding

查看:100
本文介绍了检测结构是否有填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果struct/class是否有填充,是否有一种方法(特征)?

Is there a way (trait or so) to detect, if struct/class has some padding?

我不需要跨平台或标准化的解决方案,而对于MSVC2013则需要它.

I don't need cross-platform or standardized solution, I need it for 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 ++不允许(据我所知)生成这种非侵入性的(不涉及现有结构)

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{};

编辑-为什么需要此功能?

我正在使用现有的序列化系统,该系统存储一些仅将void*传递给它们的结构(在通用函数内部)并存储sizeof(T)字节数...此类二进制文件在我们所针对的平台上不可移植,因为使用了不同的编译器,所以不能保证填充的方式.如果我可以静态检测到所有带有填充的结构T,我可以强制用户手动插入填充(某些控制填充,例如不仅仅是随机垃圾),这样就不会出现随机"填充.另一个冒险是,当我比较两个具有相同场景场景的保存文件时,它们将看起来相同.

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.

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

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)

推荐答案

在运行时是否需要此信息? 因为如果您想在构建时知道它,我相信您可以使用 static_assert 以获得此信息.

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.

这篇关于检测结构是否有填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆