A few examples of what I'm referring to:
typedef struct SOME_STRUCT {
unsigned int x1;
unsigned int x2;
unsigned int x3;
unsigned int x4;
// What I expected would work, but doesn't; the 2nd parameter gets
// turned into an 8-bit quantity at some point within memset
SOME_STRUCT() { memset( this, 0xFEEDFACE, sizeof( *this ) ); }
// Something that worked, but seems hokey/hackish
SOME_STRUCT() {
unsigned int *me = (unsigned int *)this;
for( int ii = 0; ii < sizeof(*this)/sizeof(*me); ++ii ) {
me[ii] = 0xFEEDFACE;
}
}
// The far-more-verbose-but-C++-way-of-doing-it
// This works, but doesn't lend itself very well
// to being a drop-in way to pull this off on
// any struct.
SOME_STRUCT() : x1( 0xFEEDFACE )
, x2( 0XFEEDFACE )
, x3( 0XFEEDFACE )
, x4( 0XFEEDFACE ) {}
// This would work, but I figured there would be a standard
// function that would alleviate the need to do it myself
SOME_STRUCT() { my_memset( this, 0xFEEDFACE, sizeof(*this) ); }
}
I can't use valgrind here, and my options are limited as far as various debugging libraries I have access to -- which is why I'm doing it myself for this one-off case.
Here’s a partial example of using std::generate()
safely:
#include <algorithm>
struct Wizard {
size_t i;
static unsigned char magic[4];
Wizard() : i(0) {}
unsigned char operator()() {
size_t j = i++;
i %= sizeof(magic); // Not strictly necessary due to wrapping.
return magic[j];
}
};
unsigned char Wizard::magic[4] = {0xDE,0xAD,0xBE,0xEF};
std::generate(reinterpret_cast<unsigned char*>(this),
reinterpret_cast<unsigned char*>(this) + sizeof(*this),
Wizard());
(Of course, the endianness may or may not be right, depending on how you’re looking and what you’re expecting to see when you do!)
I would declare this constructor:
SOME_STRUCT( unsigned int magic) : x1 (magic), x2 (magic), x3 (magic), x4 (magic) {}
This is very similar to your third option, and seems to be the natural C++ way of doing it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With