Violating strict-aliasing rules yields undefined behavior, e.g. when sending a struct over the network into a char buffer, and then that char pointer is C-style/reinterpret_cast
casted to a struct pointer.
The C++ std::bit_cast()
function looks like it could be used to cast such pointers in an (implementation?) defined way, i.e. without violating strict-aliasing rules.
Example:
#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;
}
So the caller of get_sock_addr()
somehow obtained a sockaddr
pointer and has determined that it actually points to a sockaddr_in
struct.
So, is such pointer casting via std::bit_cast()
a valid use-case?
Or does it somehow yield undefined behavior, as well?
If it's defined behavior, does the standard classify such pointer-casting as implementation-defined behavior?
The std::bit_cast()
proposal mentions:
If no value representation corresponds to To's object representation then the returned value is unspecified.
So is a standard-conforming compiler possible where different pointer representations are incompatible such that they can't correspond to each other?
reinterpret_cast
. – Blessedsockaddr *a = getfromsomewhere(); if (a->sa_family == AF_INET) addr = get_sock_addr(a); ... } ...
the sockaddr_in object is accessed via 2 aliasing pointers of types which aren't covered by the strict-aliasing rules, correct? – Acostasockaddr_in
struct”. The code you just gave tries to validate that assumption but is actually incompatible with it (unfortunately, since this is how traditional C interfaces are designed). The common-initial-subsequence rules are meant to allow this sort of tagging, but they require an actual union. – Blessed