如何仅将类的填充字节清零? [英] How can I zero just the padding bytes of a class?

查看:118
本文介绍了如何仅将类的填充字节清零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一个类的填充字节设置为0,因为我是以字节级别保存/加载/比较/哈希实例,而垃圾初始化的填充会在每个操作中引入不确定性.

我知道这将实现我想要的(对于普通可复制类型):

struct Example
{
    Example(char a_, int b_)
    {
        memset(this, 0, sizeof(*this));
        a = a_;
        b = b_;
    }
    char a;
    int b;
};

我不喜欢这样做,有两个原因:我喜欢构造函数初始化列表,并且我知道将位设置为0并不总是与零初始化相同(例如,指针和浮点数不一定具有全为0的零值.

顺便说一句,它显然限于普通可复制的类型,但这对我来说不是问题,因为我上面列出的操作(按字节级别的加载/保存/比较/哈希)仍然需要普通可复制的类型. /p>

我想要的是这样的[魔术]片段:

struct Example
{
    Example(char a_, int b_) : a(a_), b(b_)
    {
        // Leaves all members alone, and sets all padding bytes to 0.
        memset_only_padding_bytes(this, 0);
    }
    char a;
    int b;
};

我怀疑这样的事情是可能的,所以如果有人可以提出一个不丑陋的选择...我全是耳朵:)

解决方案

我不知道在纯C ++中完全自动执行此操作的方法.我们使用自定义代码生成系统来完成此任务(除其他外).您可以通过向其提供所有成员变量名称的宏来完成此操作.它只会在offsetof(memberA)+ sizeof(memberA)和offsetof(memberB)之间寻找孔.

或者,在成员基础上而不是作为二进制blob进行序列化/散列.那是十种清洁剂.

哦,还有另一个选择-您可以提供一个operator new,在返回内存之前它会明确清除内存.我不喜欢这种方法,但是.....不适用于堆栈分配.

I want to set the padding bytes of a class to 0, since I am saving/loading/comparing/hashing instances at a byte level, and garbage-initialised padding introduces non-determinism in each of those operations.

I know that this will achieve what I want (for trivially copyable types):

struct Example
{
    Example(char a_, int b_)
    {
        memset(this, 0, sizeof(*this));
        a = a_;
        b = b_;
    }
    char a;
    int b;
};

I don't like doing that though, for two reasons: I like constructor initialiser lists, and I know that setting the bits to 0 isn't always the same as zero-initialisation (e.g. pointers and floats don't necessarily have zero values that are all 0 bits).

As an aside, it's obviously limited to types that are trivially copyable, but that's not an issue for me since the operations I listed above (loading/saving/comparing/hashing at a byte level) require trivially copyable types anyway.

What I would like is something like this [magical] snippet:

struct Example
{
    Example(char a_, int b_) : a(a_), b(b_)
    {
        // Leaves all members alone, and sets all padding bytes to 0.
        memset_only_padding_bytes(this, 0);
    }
    char a;
    int b;
};

I doubt such a thing is possible, so if anyone can suggest a non-ugly alternative... I'm all ears :)

解决方案

There's no way I know of to do this fully automatically in pure C++. We use a custom code generation system to accomplish this (among other things). You could potentially accomplish this with a macro to which you fed all your member variable names; it would simply look for holes between offsetof(memberA)+sizeof(memberA) and offsetof(memberB).

Alternatively, serialize/hash on a memberwise basis, rather than as a binary blob. That's ten kinds of cleaner.

Oh, one other option -- you could provide an operator new which explicitly cleared the memory before returning it. I'm not a fan of that approach, though..... it doesn't work for stack allocation.

这篇关于如何仅将类的填充字节清零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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