Home > database >  Compiler disagreement on using std::vector in constexpr context
Compiler disagreement on using std::vector in constexpr context

Time:09-17

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};});
}

Compiler Explorer

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.

  • Related