抑制编译器警告

问题描述 投票:0回答:2

C++ 如何在编译时抑制此警告消息?

警告:

regen.cpp:531:30: warning: 'void* memset(void*, int, size_t)' clearing an object of type 'REGEN' {aka 'struct regen'} with no trivial copy-assignment; use assignment or value-initialization instead [-Wclass-memaccess]
  531 |   memset(&tmp, 0, sizeof(tmp));

代码:

REGEN tmp;
memset(&tmp, 0, sizeof(tmp));
c++ g++
2个回答
0
投票

您必须在构造函数(或任何用户定义的初始化函数)中单独清除对象的数据。这样做:

typedef struct regen {
    regen() {
        memset(_someData, 0, 128);
    }
    char _someData[128];
} REGEN;

在 C++ 中,您不能像在 C 中那样直接覆盖对象的字节,因为与 C 不同,C++ 编译器从其源生成一些更复杂的低级信息(文本/数据)。例如,某些类/结构的对象可能包含一个名为 VTable 的附加数据结构,用于提供运行时多态性功能,并且直接在该对象上执行 memset() 时该数据可能会被损坏。
作为参考,请参阅 GCC 的文档(C++ dialect options(GCC))。转到 -Wclass-memaccess 部分,其中提到以下内容:

-Wclass-memaccess(仅限 C++ 和 Objective-C++)

当对原始内存函数(例如 memset 或 memcpy)的调用目标是类类型的对象时发出警告,并且写入此类对象时可能会绕过类非平凡或已删除的构造函数或复制赋值,违反常量正确性或封装或损坏的虚拟表指针。修改此类对象的表示可能会违反类的成员函数维护的不变量。例如,下面对 memset 的调用是未定义的,因为它修改了一个不平凡的类对象,因此被诊断出来。初始化或清除此类类型对象的存储的安全方法是使用适当的构造函数或赋值运算符(如果可用)。

std::string str = "abc";
memset(&str, 0, sizeof str);

-Wclass-memaccess 选项由 -Wall 启用。将指向类对象的指针显式转换为 void * 或原始内存函数可以安全访问的类型可以抑制警告。

我不是 C++ 大神,但我希望这能在某种程度上有所帮助。


0
投票

你必须向编译器表明你确切地知道你在做什么。 在你的例子中:

REGEN tmp;
memset((char*)&tmp, 0, sizeof(tmp));
© www.soinside.com 2019 - 2024. All rights reserved.