The following code compiles with gcc and MSVC, but not with clang.
#include <array>
#include <vector>
consteval void foo(auto func) {
std::array<int, func().size()> f;
}
int main() {
foo([](){ return std::vector<int>{1,2,3,4,5};});
}
If I understand the rules of dynamic memory allocation in constant expressions correctly, this should be allowed because the memory is deallocated immediately. Is this a bug in clang? Or even undefined behaviour?
CodePudding user response:
It is just a bug in Clang. It seems to not consider the deallocations happening at the end of expressions as template arguments as part of the constant (full-)expression. When using a constexpr
variable to store the size instead of a template argument, Clang accepts it as well.
A simplified test case (not depending on std::vector
constexpr support):
struct V {
int* v = new int[10];
constexpr ~V() { delete[] v; }
constexpr int size() { return 10; }
};
template<auto>
struct A {};
int main() {
constexpr auto x = V{}.size(); //1
using T = A<V{}.size()>; //2
}
Clang accepts //1
, but not //2
.
On a quick look at https://github.com/llvm/llvm-project/issues I couldn't find a matching issue, so it might make sense to report it.