struct A {
consteval A() {};
};
constexpr bool g() {
auto a = new A;
delete a;
return true;
}
int main() {
static_assert(g());
}
https://godbolt.org/z/jsq35WxKs
GCC 和 MSVC 拒绝该程序,ICC 和 Clang 接受它:
///MSVC:
<source>(6): error C7595: 'A::A': call to immediate function is not a constant expression
Compiler returned: 2
//GCC:
<source>: In function 'constexpr bool g()':
<source>:6:18: error: the value of '<anonymous>' is not usable in a constant expression
6 | auto a = new A;
| ^
<source>:6:18: note: '<anonymous>' was not declared 'constexpr'
<source>:7:12: error: type '<type error>' argument given to 'delete', expected pointer
7 | delete a;
| ^
Compiler returned: 1
虽然,替换new A
为new A()
导致 GCC 也接受该程序(但两者都不new A{}
是)。
至少进行以下更改之一会导致所有四个编译器都接受该程序:
替换
consteval
为constexpr
替换
constexpr
为consteval
代替
auto a = new A; delete a;
和
auto alloc = std::allocator<A>{}; auto a = alloc.allocate(1); std::construct_at(a); std::destroy_at(a); alloc.deallocate(a, 1);
有
A a;
, 有auto&& a = A{};
或 有A{};
只有例外:
带有 libstdc++ 的 Clang 主干
std::allocator
似乎由于不相关的错误而无法使用该版本进行编译。对于 Clang 13 或 libc++,它也被接受。In file included from <source>:1: In file included from [...]/memory:78: [...]/shared_ptr_atomic.h:459:14: error: missing 'typename' prior to dependent type name '_Atomic_count::pointer' static _Atomic_count::pointer
std::allocator
只要consteval
构造函数上有, MSVC 就会拒绝该版本:error C7595: 'A::A': call to immediate function is not a constant expression <source>(10): note: see reference to function template instantiation '_Ty *std::construct_at<_Ty,,void>(_Ty *const ) noexcept(false)' being compiled with [ _Ty=A ]
完全替换或删除调用似乎static_assert(g());
对g()
这些结果没有任何影响。
哪些编译器是正确的,如果原始编译器格式不正确,为什么只不允许使用限定符和构造方法的特定组合?
受到此答案下的评论的启发。