使用 memset 清除非平凡类型的对象时出错
error clearing an object of non-trivial type with memset
好吧,事情很简单,我明白了
warning: ‘void* memset(void*, int, size_t)’ clearing an object of non-trivial type ‘struct FormatHashBuffers(CBlock*, char*, char*, char*)::<unnamed>’; use assignment or value-initialization instead [-Wclass-memaccess] memset(&tmp, 0, sizeof(tmp));
关于这个函数,我知道为什么,当我用 g++ 5 构建时没有警告,但是当我用 7.1 或 8.5 构建时我收到警告,知道为什么或如何解决它吗?提前致谢。
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata,
char* phash1) {
//
// Pre-build hash buffers
//
struct
{
struct unnamed2
{
int nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
unsigned int nTime;
unsigned int nBits;
unsigned int nNonce;
}
block;
unsigned char pchPadding0[64];
uint256 hash1;
unsigned char pchPadding1[64];
}
tmp;
memset(&tmp, 0, sizeof(tmp));
tmp.block.nVersion = pblock->nVersion;
tmp.block.hashPrevBlock = pblock->hashPrevBlock;
tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
tmp.block.nTime = pblock->nTime;
tmp.block.nBits = pblock->nBits;
tmp.block.nNonce = pblock->nNonce;
FormatHashBlocks(&tmp.block, sizeof(tmp.block));
FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
// Byte swap all the input buffer
for (unsigned int i = 0; i < sizeof(tmp) / 4; i++)
((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
// Precalc the first half of the first hash, which stays constant
SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
memcpy(pdata, &tmp.block, 128);
memcpy(phash1, &tmp.hash1, 64);
}
any idea why
显然,-Werror 标志没有为您的 g++ v5 环境正确设置,或者当时的开发人员没有考虑到。它应该始终产生此警告。
how to solve it?
这里干脆不引用memset!由于至少相比之下存在 SHA256Transform(),因此在这里可以忽略可能的性能问题,因此您应该更喜欢在这里进行干净的显式初始化。尽量避免嵌套结构(因为内部已经在更“全局”的范围内进一步使用)并参考aggregate/uniform初始化或显式工厂方式。
您可以默认初始化您的成员变量:
struct {
struct unnamed2 {
int nVersion{};
uint256 hashPrevBlock{};
uint256 hashMerkleRoot{};
unsigned int nTime{};
unsigned int nBits{};
unsigned int nNonce{};
} block;
unsigned char pchPadding0[64]{};
uint256 hash1{};
unsigned char pchPadding1[64]{};
} tmp;
这样就不需要 memset(&tmp, 0, sizeof(tmp));
并且警告会消失。
要初始化结构变量,您可以使用
tmp = {};
好吧,事情很简单,我明白了
warning: ‘void* memset(void*, int, size_t)’ clearing an object of non-trivial type ‘struct FormatHashBuffers(CBlock*, char*, char*, char*)::<unnamed>’; use assignment or value-initialization instead [-Wclass-memaccess] memset(&tmp, 0, sizeof(tmp));
关于这个函数,我知道为什么,当我用 g++ 5 构建时没有警告,但是当我用 7.1 或 8.5 构建时我收到警告,知道为什么或如何解决它吗?提前致谢。
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata,
char* phash1) {
//
// Pre-build hash buffers
//
struct
{
struct unnamed2
{
int nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
unsigned int nTime;
unsigned int nBits;
unsigned int nNonce;
}
block;
unsigned char pchPadding0[64];
uint256 hash1;
unsigned char pchPadding1[64];
}
tmp;
memset(&tmp, 0, sizeof(tmp));
tmp.block.nVersion = pblock->nVersion;
tmp.block.hashPrevBlock = pblock->hashPrevBlock;
tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
tmp.block.nTime = pblock->nTime;
tmp.block.nBits = pblock->nBits;
tmp.block.nNonce = pblock->nNonce;
FormatHashBlocks(&tmp.block, sizeof(tmp.block));
FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
// Byte swap all the input buffer
for (unsigned int i = 0; i < sizeof(tmp) / 4; i++)
((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
// Precalc the first half of the first hash, which stays constant
SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
memcpy(pdata, &tmp.block, 128);
memcpy(phash1, &tmp.hash1, 64);
}
any idea why
显然,-Werror 标志没有为您的 g++ v5 环境正确设置,或者当时的开发人员没有考虑到。它应该始终产生此警告。
how to solve it?
这里干脆不引用memset!由于至少相比之下存在 SHA256Transform(),因此在这里可以忽略可能的性能问题,因此您应该更喜欢在这里进行干净的显式初始化。尽量避免嵌套结构(因为内部已经在更“全局”的范围内进一步使用)并参考aggregate/uniform初始化或显式工厂方式。
您可以默认初始化您的成员变量:
struct {
struct unnamed2 {
int nVersion{};
uint256 hashPrevBlock{};
uint256 hashMerkleRoot{};
unsigned int nTime{};
unsigned int nBits{};
unsigned int nNonce{};
} block;
unsigned char pchPadding0[64]{};
uint256 hash1{};
unsigned char pchPadding1[64]{};
} tmp;
这样就不需要 memset(&tmp, 0, sizeof(tmp));
并且警告会消失。
要初始化结构变量,您可以使用
tmp = {};