Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler disagreement on using std::vector in constexpr context

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?

like image 495
florestan Avatar asked Sep 01 '26 18:09

florestan


1 Answers

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.

like image 58
user17732522 Avatar answered Sep 03 '26 07:09

user17732522



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!