以下代码可以使用 clang++ 14 进行编译,但不能使用 g++ 12 进行编译(失败是因为 constexpr 中不允许使用
reinterpret_cast
)。
constexpr int* convert(char* a) {
return (int*)(a);
}
int main() {
return (int) *convert(new char('a'));
}
为什么 clang 允许这种 C 风格的转换,而 gcc 不允许?
在 P2448R2 之前,如果
constexpr
函数永远无法生成常量表达式,则您的程序将是格式错误的,无需诊断。这是“允许编译器检查但不必检查”的标准术语,特别是对于难以证明的事情。
你的函数符合这个定义。没有参数
a
意味着 convert(a)
将是一个常量表达式。 GCC 选择检查这个具体案例,而 Clang 没有。
P2448R2之后,这条规则被打破,不再是病态的。该函数现在是一个
constexpr
函数,只是无法在编译时调用,就像没有标记 constexpr
一样。new char[sizeof(int)]{}
,则不会有未定义的行为。
根据 https://gcc.gnu.org/projects/cxx-status.html,P2448R2 在 GCC 14(开发分支)中实现。果然,您的代码现在可以使用 GCC 14 进行编译。