最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Can std::bit_cast convert to or from std::nullptr_t type? - Stack Overflow

programmeradmin0浏览0评论

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
  • 1 "If there is no value of type 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:44
  • I would say that nullptr has no byte representation ("empty" type), so nothing for int. – Jarod42 Commented Mar 28 at 12:45
  • 1 It is very unlikely that an arbitrary pointer has the same value representation as nullptr - the only value of type nullptr_t - in which case the cast is undefined. It is much more likely that the null pointer of an arbitrary type does. Perhaps you meant int* p = 0;? With that, all compilers produce 1 1. (Not posting an answer since I don't know if that is well defined.) – molbdnilo Commented Mar 28 at 12:59
  • 1 cppreference says UB. I cannot find the same wording in the standard (the closest is about conversion to pointer type that should be the same as (void *)0). – Oersted Commented Mar 28 at 13:02
  • 1 also: open-std./jtc1/sc22/wg14/www/docs/…) – Oersted Commented Mar 28 at 13:05
 |  Show 4 more comments

1 Answer 1

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.

发布评论

评论列表(0)

  1. 暂无评论