What's so hard about constexpr allocation? -- Barry Revzin
Before C++20, constant evaluation couldn't handle allocations, causing any such attempts to fail. This changed with C++20, which introduced the ability to allocate memory during constant evaluation, although with strict limitations requiring deallocation during the same evaluation period. Despite these advancements, certain operations, such as declaring a constexpr std::vector
, remain impossible, with the goal of this blog post being to explore why these limitations persist.
What's so hard about
constexpr
allocation?by Barry Revzin
From the article:
Before C++20, we couldn’t have any allocation during constant evaluation at all. Any attempt to do so would fail the evaluation — it would no longer be constant.
In C++20, as a result of P0784R7, that changed. Finally we could do allocation during constant evaluation. However, this evaluation was extremely limited. Specifically, any allocation that happens must be deallocated during that constant evaluation.
This opened the door to a wide range of operations that weren’t possible before. We can now have local
std::string
s andstd::vector<T>
s! Those just work!But we still cannot just declare a
constexpr std::vector
:#include <vector> constexpr std::vector<int> v = {1, 2, 3}; // error
And we cannot even declare a local
constexpr std::vector
in aconsteval
function:#include <vector> consteval auto f() -> int { constexpr std::vector<int> v = {4, 5, 6}; // still error return v.size(); }
This limitation still remains in C++23 and could very well still remain in C++26. The goal of this blog post is to explain why we haven’t just solved this problem already.