3

I've run into the following error:

class NormalClass
{
public:
    constexpr NormalClass() : arr{}, debug_ptr((int*)arr)
    {
//'reinterpret_cast' is not a constant expression
//cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
    }

public:

    char arr[5];
    int* debug_ptr;


};

constinit NormalClass normal;

int main()
{

}

Originally this was in a template, with (T*) cast. Why is it that a cast like this isn't allowed in a constexpr?

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • Whether the compiler would use `reinterpret_cast` for `(T*)` or not depends on the type that is cast, and the type it is cast to. If it works with `(T*)` then the compiler didn't choose `reinterpret_cast` – t.niese Sep 04 '21 at 11:01
  • 1
    With the title, the question might be a duplicate to [Why is reinterpret_cast not constexpr?](https://stackoverflow.com/questions/59913275/why-is-reinterpret-cast-not-constexpr) You might want to show the code with a [mcve] that utilizes the template and `(T*)` including the types involved with the cast and the same for your current example, and then it would be possible to tell why the one works and the other not – t.niese Sep 04 '21 at 11:08
  • Not an answer; but if you replace both occurrences of `int*` with `unsigned int` (or `unsigned long` in a 64-bit environment), it compiles without warnings. – TonyK Sep 04 '21 at 11:19
  • This is probably for the best as don't think that's a valid cast. How would you ever get to the last element of the `char` array? – WBuck Sep 04 '21 at 11:39
  • Oh it came up when I had my own array container that had a char buffer, and I couldn't see anything in it in the debugger through the char pointer, so I wanted to create a debug pointer cast to T. – Zebrafish Sep 04 '21 at 12:11
  • If your compiler has good enough C++20 coverage, you could try using [`std::bit_cast`](https://en.cppreference.com/w/cpp/numeric/bit_cast) to do the cast. It's `constexpr`. _"couldn't see anything in it in the debugger through the char pointer"_ might be best to study your debugger docs - there's usually an easy way to tell it to display memory content as if it contained some arbitrary type. – Tony Delroy Sep 04 '21 at 12:35

2 Answers2

3

See https://en.cppreference.com/w/cpp/language/constant_expression

Core constant expressions

A core constant expression is any expression whose evaluation would not evaluate any one of the following:

    1. reinterpret_cast
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
3

Why can't reinterpret_cast be used in a constant expression?

Because the C++ language spec says so. See [expr.const]/5.15:

An expression E is a core constant expression unless the evaluation of E, ... would evaluate one of the following:

5.15   a reinterpret_­cast ([expr.reinterpret.cast]);


Also note that reinterpreting char[] as int and then accessing it is undefined behavior - a strict aliasing violation. As soon as the pointer debug_ptr is dereferenced in the actual program, there will be UB.

rustyx
  • 80,671
  • 25
  • 200
  • 267
  • That's really the one I was looking for ;) Couldn't find the reference quickly enough. Thanks – Pepijn Kramer Sep 04 '21 at 12:53
  • To avoid strict aliasing what can you do if you want an int pointer pointing to the char buffer? And don't say create an int array instead. – Zebrafish Feb 23 '23 at 12:48