c++ - -Wclass-memaccess 带有 boost::endian 和 gcc 的警告
问题描述
我得到了一个-Wclass-memaccess
gcc >= 8 ,我想知道我是否可以安全地忽略警告。
测试用例:
#include <array>
#include <boost/endian/buffers.hpp>
int main()
{
static_assert(std::is_trivial<boost::endian::big_uint16_buf_t>::value);
static_assert(std::is_trivially_copyable<boost::endian::big_uint16_buf_t>::value);
// No warning when buffer is char*
{
std::array<char, 2> buffer{0x0, 0x1};
boost::endian::big_uint16_buf_t v;
std::memcpy(&v, buffer.data(), sizeof(v));
}
// -Wclass-memaccess when buffer is std::byte*
{
std::array<std::byte, 2> buffer{std::byte{0x0}, std::byte{0x1}};
boost::endian::big_uint16_buf_t v;
std::memcpy(&v, buffer.data(), sizeof(v));
}
}
背景:这种类型的代码用于解码二进制网络流量,memcpy 用于安全,具有严格的别名规则。
在更大的代码库上更广泛地使用该模式之前,我想确保它没有缺陷。
我的印象是复制到 boost::endian 缓冲区是安全的。奇怪的是,当缓冲区是指向的指针时没有警告char
,但只有当缓冲区是指向的指针时std::byte
完整的警告信息是:
prog.cc: In function 'int main()':
prog.cc:23:49: warning: 'void* memcpy(void*, const void*, size_t)' copying an object of type 'boost::endian::big_uint16_buf_t' {aka 'class boost::endian::endian_buffer<boost::endian::order::big, short unsigned int, 16>'} with 'protected' member 'boost::endian::endian_buffer<boost::endian::order::big, short unsigned int, 16>::m_value' from an array of 'std::array<std::byte, 6>::value_type' {aka 'enum class std::byte'}; use assignment or copy-initialization instead [-Wclass-memaccess]
23 | std::memcpy(&v, buffer.data(), sizeof(v));
| ^
In file included from prog.cc:2:
/opt/wandbox/boost-1.70.0/gcc-9.1.0/include/boost/endian/buffers.hpp:375:11: note: 'boost::endian::big_uint16_buf_t' {aka 'class boost::endian::endian_buffer<boost::endian::order::big, short unsigned int, 16>'} declared here
375 | class endian_buffer< order::big, T, n_bits, align::no >
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
解决方案
推荐阅读
- java - 代理身份验证 selenium java
- c# - Unity CheckSphere 或 OverlapSphere
- google-signin - JavaScript API 启动登录流程以使用 Google 库进行新登录
- c++ - 禁止警告消息“此项目包含可能不安全的附件”Outlook 附件外发邮件
- c# - 在本地运行测试时忽略 OneTimeSetup 和 TearDown
- lattice-diamond - Lattice Diamond Synthesis 退出并出现错误代码 999
- cisco - 带有 tcpdump 的 CDP - 如何区分“主干”或“访问”端口?
- typescript - 日期差异并将差异添加到新日期
- html - 标签 id 和 aria-labelledby 的区别用法
- python - 导入一个未打包模块的python类,并在它自己的线程中运行