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:
- Clang prints
0 1
. - GCC prints
1 0
. - MSVC prints
1 1
.
Online demo:
Which implementation is correct here if any?
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:
- Clang prints
0 1
. - GCC prints
1 0
. - MSVC prints
1 1
.
Online demo: https://gcc.godbolt./z/fbEGvGs4v
Which implementation is correct here if any?
Share Improve this question asked Mar 28 at 12:36 FedorFedor 21.6k37 gold badges55 silver badges168 bronze badges 9 | Show 4 more comments1 Answer
Reset to default 8[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.
To
corresponding to the value representation produced, the behavior is undefined. If there are multiple such values, which value is produced is unspecified." – Jarod42 Commented Mar 28 at 12:44nullptr
has no byte representation ("empty" type), so nothing forint
. – Jarod42 Commented Mar 28 at 12:45nullptr
- the only value of typenullptr_t
- in which case the cast is undefined. It is much more likely that the null pointer of an arbitrary type does. Perhaps you meantint* p = 0;
? With that, all compilers produce1 1
. (Not posting an answer since I don't know if that is well defined.) – molbdnilo Commented Mar 28 at 12:59(void *)0
). – Oersted Commented Mar 28 at 13:02