违反严格的别名规则会产生未定义的行为,例如,通过网络将结构发送到char缓冲区时,然后该char指针被C样式/std::reinterpret_cast()
强制转换为结构指针。
C++std::bit_cast()
函数看起来可以用于以(实现?(定义的方式投射此类指针,即不违反严格的别名规则。
示例:
#include <sys/types.h>
#include <netinet/in.h>
#include <bit>
int get_sock_addr(const struct sockaddr *a)
{
struct sockaddr_in *x = std::bit_cast<struct sockaddr_in*>(a);
return x->sin_addr.s_addr;
}
因此,get_sock_addr()
的调用者不知何故获得了一个sockaddr
指针,并确定它实际上指向一个sockaddr_in
结构。
那么,通过std::bit_cast()
进行指针强制转换是一个有效的用例吗?
或者它也会以某种方式产生未定义的行为?
如果它是定义的行为,那么标准是否将这种指针转换归类为实现定义的行为?
std::bit_cast()
提案提到:
如果没有值表示与to的对象表示相对应,则返回的值未指定。
那么,在不同的指针表示不兼容,以至于它们不能相互对应的情况下,一个符合标准的编译器可能吗?
转换指针值是无关紧要的。重要的是对象。您有一个指向X类型对象的指针,但指针的类型是Y。试图通过指向不相关类型Y的指针/引用访问X类型对象是UB的来源。
你是如何获得这些指针的基本上是无关紧要的。所以bit_cast
在这方面并不比reinterpret_cast
好。
如果那里没有sockaddr_in
,那么你就不能假装有。然而,C++20中的隐式对象创建可能已经解决了这个问题,这取决于您的代码。如果是这样,那么它仍然不管你如何获得指针。