2

The latest C++20 standard supports dynamic allocation memory in compile time with a limitation. The memory allocation cannot "go outside" the constant expression. That means that vector cannot be return and stored in a constexpr variable.

In the cppstories article there is the following example

#include <vector>
#include <string>
#include <algorithm>
constexpr std::vector<std::string> 
split(std::string_view strv, std::string_view delims = " ") {
 std::vector<std::string> output;
 size_t first = 0;
 while (first < strv.size()) {
 const auto second = strv.find_first_of(delims, first);
 if (first != second)
 output.emplace_back(strv.substr(first, second-first));
 if (second == std::string_view::npos)
 break;
 first = second + 1;
 }
 return output;
}
constexpr size_t numWords(std::string_view str) {
 const auto words = split(str);
 return words.size();
}
int main() {
 static_assert(numWords("hello world abc xyz") == 4);
}

This example compiles successfully. If I change

const auto words = split(str);

to

constexpr auto words = split(str);

I get following error

example.cpp (27): error C2131: expression did not evaluate to a constant (27): note: failure was caused by a read of a variable outside its lifetime (27): note: see usage of 'str' Compiler returned: 2

Based on the standard this expected since the compilers don’t support so-called "non-transient" memory allocations. But why no error is reported when const is used. In bot cases the code is executed in compile time

Barry
312k33 gold badges739 silver badges1.1k bronze badges
asked Apr 25, 2025 at 14:22
1
  • 1
    const is not needed in this context: godbolt.org/z/65Pq1z9hW Commented Apr 25, 2025 at 14:35

2 Answers 2

13

This has nothing to do with allocation.

When you attempted to write

constexpr auto words = split(str);

Declaring a constexpr variable starts a new constant evaluation. Yes, we happen to be inside of one already (the outer static_assert call), but declaring a constexpr variable (or initializing a constant template argument or the condition of an if constexpr or ...) start a new.

Each new constant evaluation has to be complete in of itself. Here, we don't know what str is. We didn't see its initialization. So we cannot evaluate this as a constant. That's the error:

note: failure was caused by a read of a variable outside its lifetime
note: see usage of 'str'


This is the same issue as you'd see in this example:

constexpr int plus_one(int x) {
 const int y = x + 1;
 return y;
}
static_assert(plus_one(4) == 5);

If you change the declaration of y to be constexpr instead of const, this also wouldn't compile anymore (because: what is x?).

answered Apr 25, 2025 at 14:32
Sign up to request clarification or add additional context in comments.

Comments

0

You're correct, c++ 20 does allows dynamic memory in constexpr but only within the expression's scope.

constexpr auto words = split(str);

When you use the const, it runs at compile-time because of the static_assert, but the result doesn't need to be in constexpr .

This fails because it tries to extend the lifetime of str, which is not allowed in the constant expressions due to standard rules .

And const doesn't set of the stick check, so no get's no error there.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.