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.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句