1

Is the following program formally correct C++?

#include <iostream>
#define CASE 1
#if CASE==1
  constexpr void* crash = static_cast<void*>(static_cast<char*>(nullptr)+1);
#elif CASE==2
  constexpr void* crash = nullptr;
#elif CASE==3
  const void* crash = static_cast<void*>(static_cast<char*>(nullptr)+1);
#endif
int main() {
    std::cout << "Crash: " << crash << "\n";
}

G++ 8.4.0 reports

error: reinterpret_cast from integer to pointer
   constexpr void* crash = static_cast<void*>(static_cast<char*>(nullptr)+1);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Visual Studio 19 cl reports:

null.cc(3): error C2131: expression did not evaluate to a constant
null.cc(3): note: failure was caused by unevaluable pointer value

How are those error messages to be interpreted?

If I change the value of CASE to 2 or 3 the compilation succeeds with both compilers and a run of the compiled program gives the expected results.

Tobias
  • 5,038
  • 1
  • 18
  • 39

1 Answers1

2

You cannot perform arithmetic on just any pointer in constexpr.
You can perform arithmetic on pointers to arrays (or objects as one sized arrays) as long as you don’t end up outside the array.

Daniel
  • 30,896
  • 18
  • 85
  • 139
  • ...or further than one element beyond the end of the array. – Bathsheba Jun 07 '21 at 09:54
  • Do the following two statements lead to your answer? If this is the case could you add them to your answer? (Statement 1) Paragraph 4 in section 8.5.6 [expr.add] of [n4713](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf) says that `static_cast(static_cast(nullptr)+1)` gives undefined behaviour. (Statement 2) Paragraph section 8.6 [expr.const] item (2.6) of paragraph 2 states that if pointer arithmetics leads to undefined behavior this is not a core constant expression. So `constexpr` is not applicable to this expression and leads to an error. – Tobias Jun 08 '21 at 07:14