使用memcpy()复制到std :: chrono ::毫秒时出现错误-Werror = class-memaccess

问题描述 投票:-4回答:3

对于下面的代码,gcc给了我错误,并说我试图从数组中复制chrono :: milliseconds类型的对象,而应该使用赋值或复制初始化:

std::array<unsigned char, 6> myArray = {123, 123, 112, 0, 15};
std::chrono::milliseconds dest{0};
memcpy(&dest, &myArray, 5);

当我只需要从数组而不是整个数组中复制5个字节时,处理此问题的最佳方法是什么?

c++ gcc g++ memcpy chrono
3个回答
2
投票

您可以像这样初始化持续时间:

std::chrono::milliseconds::rep r = 0;
// initialise r with your array
std::chrono::milliseconds dest{r};

现在,需要弄清楚如何初始化r。您可以使用memcpy,但是在目标系统上数组的格式和整数表示之间将存在依赖关系。换句话说,程序读取的数据将在不兼容的系统之间不兼容。

实现整数反序列化的可移植方法是指定数据格式-通常选择大字节序字节。确定输入格式后,就可以使用移位,位掩码和按位或运算将各个八位位组合为一个整数值。尽管这通常很简单,但容易犯一些错误(尤其是带符号的整数),因此,我建议使用现有的解决方案。标准库不具有反序列化功能。


0
投票

由于std::chrono::durationmilliseconds是其变体)类型不是Trivially Copyable,因此在其上复制随机数据会引起编译器警告。

虽然有一些方法可以禁止显示这些警告,但不清楚为什么首先要尝试这样做。我有充分的理由相信,即使没有警告,您想要做的事情也不会给您带来预期的结果。


0
投票

std::chrono::milliseconds中的时间由std::milli表示,恰好包含std::intmax_t字段。但是您不知道这些类的布局,尚未定义,并且std::chrono::milliseconds对象的地址可能与数据开头的地址不匹配。所以您要做的几乎都是UB。

处理此问题的正确方法是,以定义的方式形成适当的算术值,并通过定义的功能对其进行分配。

© www.soinside.com 2019 - 2024. All rights reserved.