如何解决修改char数组后,reintrepret_cast到char *的定义是否正确?
从套接字接收到预期的消息时,请考虑以下示例:
struct myData {
uint8_t type;
int value;
}
myData readFromSocket(int socketFD) {
myData data{};
ssize_t bytes = recv(socketFD,reinterpret_cast<char*>(&data),sizeof(myData),0);
if(bytes == sizeof(myData))
return data;
return myData{};
}
在此示例中,尚不清楚行为是否定义明确。
根据reintrpret_cast on cppreference.com,对于 exammination ,该行为已得到很好的定义,因为char的对齐方式不如myData对齐,并且由于类型转换专门针对char指针。对于我来说,目前尚不清楚检查是专门用于读取还是包含对强制转换指针的写入。
5)正在解释:
任何对象指针类型T1 *都可以转换为另一对象指针类型cv T2 *。这完全等效于static_cast
(static_cast (expression))(这意味着如果T2的对齐要求不严格于T1的对齐要求,则指针的值不会更改,并且转换所得的指针返回原始类型会产生原始值)。无论如何,只有在类型别名规则允许的情况下,才能安全地取消对结果指针的引用(见下文)
和类型别名的第三点:
AliasedType为std :: byte(自C ++ 17起),char或无符号char:这允许将任何对象的对象表示形式检查为字节数组。
我已经测试了与上面类似的代码,没有任何问题,但是由于所有这些都归结于什么优化,编译器使我很难给出确切的例子来说明可能会失败的地方。
This article提到了朝另一个方向(即从char*
到myData
的转换会受到不确定的行为的影响,并建议使用memcpy()
。我的假设是得出这个结论,因为类型别名规则未涵盖强制类型转换。
然而,this mail thread怀疑memcpy()
根据标准应该提供保证(请参见下面的引用),并且在没有阅读标准的情况下我倾向于同意,因为它看起来一样对memcpy()
和recv()
进行了强制转换。
在C ++社区中,当前的想法是memcpy允许键入pun,但是IIRC C ++标准实际上甚至还不清楚为什么是这种情况,在当前的写作中,可能实际上是没有方式。
无论如何,如果有人对此有所了解并且可以阐明一点,我将不胜感激。我对此事的兴趣是学术性的,而不是实际的。我已使用c ++ 17对此进行了标记,因为这是我正在从事的工作,欢迎您对其他标准进行深入了解。
解决方法
C ++标准在[basic.lval]/p8中指定别名规则:
如果程序尝试通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
。 。 。
—char
,unsigned char
或std::byte
类型。
在[defns.access]中指定了术语 访问 :
“执行时间操作”以读取或修改对象的值
此外,没有其他规定指出混叠是单向工作的规则。
所以我们可以得出结论,混叠可以同时起作用,并且代码还可以。
但是请注意,如果要覆盖的对象包含const
个成员,则覆盖后应std::launder
个对象,否则允许编译器假定const
个成员永不更改。 / p>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。