I have a C++ concept for checking that an array of objects can be dynamically allocated:
template< class T, int N >
concept heap_constructible = requires() {
delete[] new T[N];
};
And I found accidently that compilers diverge in its evaluation in case of zero-size arrays N=0
and inaccessible (e.g. private:
) constructor:
class A {
A();
};
static_assert( !heap_constructible<A, 5> ); // OK everywhere
static_assert( heap_constructible<A, 0> ); // OK in GCC only
Only GCC seems to allow zero-size allocation of A
-objects. Clang prints the error:
calling a private constructor of class 'A'
In case of slight modification of the concept:
template< class T, int N >
concept heap_constructible1 = requires() {
delete[] new T[N]{}; // note additional empty braced list
};
Clang accepts it as well:
static_assert( heap_constructible1<A, 0> ); // OK in GCC and Clang
but not MSVC, which evaluates both heap_constructible<A, 0>
and heap_constructible1<A, 0>
to false
. Online demo: https://gcc.godbolt.org/z/nYr88avM4
Which compiler is right here?