Is it prohibited to use std::bit_cast
for conversion to or from std::nullptr_t = decltype(nullptr)
type? And if it is permitted, 1) must the result of std::bit_cast
be the same as static_cast
, 2) must the conversion back and forth return the original value?
I have tested the current compilers, and they all accept the following program without any warnings:
#include <bit>
#include <iostream>
int p = 0;
auto n = std::bit_cast<decltype(nullptr)>( &p );
int main() {
std::cout
<< (std::bit_cast<int*>(n) == static_cast<int*>(n))
<< ' '
<< (&p == std::bit_cast<int*>(n));
}
But the compilers diverge in how they treat the casts, which is visible from the output of the program:
0 1
.1 0
.1 1
.Online demo: https://gcc.godbolt.org/z/fbEGvGs4v
Which implementation is correct here if any?
[basic.types.general]/4 defines value representation as "the set of bits in the object representation of T
that participate in representing a value of type T
". [conv.lval]/3.1 says that lvalue-to-rvalue conversion on a nullptr_t
object produces a null pointer constant without even accessing its storage. It follows that the value representation of nullptr_t
is necessarily empty and every bit in its object representation is a padding bit.
That being the case, the object representation produced by a bit_cast
to nullptr_t
is entirely unspecified, and the bit_cast
back has undefined behavior because every bit in the value representation produced is indeterminate and the indeterminate bit is not contained in an unsigned char
or std::byte
object.
All three compilers are conforming.