通过 std::bit_cast()ed 指针进行别名访问

Aliasing accesses through a std::bit_cast()ed pointer

违反严格的别名规则会产生未定义的行为,例如当通过网络将结构发送到 char 缓冲区时,然后该 char 指针是 C 风格/std::reinterpret_cast() 转换为结构指针。

C++ std::bit_cast() function 看起来它可以用于以(实现?)定义的方式转换此类指针,即不违反严格的别名规则。

示例:

#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() proposal提到:

If no value representation corresponds to To's object representation then the returned value is unspecified.

那么,在不同的指针表示不兼容以至于它们不能相互对应的情况下,符合标准的编译器是否可能?

转换指针值无关紧要。重要的是对象。你有一个指向类型 X 的对象的指针,但指针的类型是 Y。试图通过 pointer/reference 访问类型 X 的对象到不相关的类型 Y 是 UB 的来源。

你是如何获得这些指针的几乎无关紧要。所以bit_cast在这方面并不比reinterpret_cast好。

如果那里没有sockaddr_in,那你就不能假装有。但是,根据您的代码,C++20 中的 implicit object creation 可能已经解决了这个问题。如果是,那么它仍然与您如何获得指针无关。