Why can't I std::bit_cast the contents of a string literal?

470 Views Asked by At

While experimenting with compile-time string manipulation, I've encountered a strange phenomenon:

#include <bit>

constexpr char str[4] = "abc";

// error: constexpr variable 'x' must be initialized by a constant expression
constexpr auto x = std::bit_cast<int>("xyz");
// OK
constexpr auto y = std::bit_cast<int>(str);

See Compiler Explorer.

How come bit-casting is permitted for a char[] which is stored in a global variable, but not for string literals? std::bit_cast does not modify its source and the result is a value, so there is no potential of modifying the storage of string literals.

1

There are 1 best solutions below

0
Jan Schultke On

std::bit_cast<int>("xyz") in a constant expression is valid in C++20. None of the criteria in [bit.cast] p3 are violated, and neither is any precondition in the prior paragraph.

It doesn't compile in clang due to a compiler bug. See llvm-project issue #63686.

No one had imagined that lvalue-to-rvalue conversion could take place for arrays in ordinary C++, but LLVM's implementation of std::bit_cast necessitates it (see ExprConstant.cpp):

if (LVal.Designator.Entries.empty()) {
  // Fail for now for LValue to RValue conversion of an array.
  // (This shouldn't show up in C/C++, but it could be triggered by a
  // weird EvaluateAsRValue call from a tool.)
  Info.FFDiag(Conv);
  return false;
}