The following code compiles with clang++ 14 but not with g++ 12 (which fails because reinterpret_cast
is not allowed in constexprs).
constexpr int* convert(char* a) {
return (int*)(a);
}
int main() {
return (int) *convert(new char('a'));
}
Why does clang allow this C-style cast while gcc doesn't?
Before P2448R2, if a constexpr
function could never produce a constant expression no matter what the arguments, your program would be ill-formed, no diagnostic required. This is standardese for "A compiler is allowed to check but doesn't have to", especially for something hard to prove.
Your function fits that definition: no argument for a
would mean that convert(a)
would be a constant expression. GCC chose to check this specific case and Clang did not.
After P2448R2, this rule was struck and it is no longer ill-formed. The function is now a constexpr
function that just can't be called at compile time, exactly as if it was not marked constexpr
.
Your current code does have undefined behaviour, but it wouldn't have undefined behaviour if you had instead had new char[sizeof(int)]{}
or (char*) new int{}
.
And according to https://gcc.gnu.org/projects/cxx-status.html, P2448R2 is implemented in GCC 14 (the development branch). And sure enough your code compiles now with GCC 14.