Post

Learner's Notes: Looking at constexpr in C++20

Study notes

https://stackoverflow.com/questions/31742318/are-all-template-instantiations-created-at-compile-time

constexpr is weirder than I thought

The constexpr keyword in C++20 has some nuances that surprised me during my exploration. To begin unraveling its behavior, let’s look at a simple example:

1
2
3
4
5
6
7
8
constexpr int times_2(const int x) {
    return 2 * x;
}

int main() {
    int x = times_2(1000);
    return x;
}

In this example, is the value of x evaluated at compile time? Well, not if you compile it without optimizations (-O0) on x86-64 clang (trunk), as shown here. However, enabling optimizations (e.g., -O1) allows the compiler to evaluate x at compile time. So, the answer is: maybe!

Now, let’s tweak the code slightly:

1
2
3
4
5
6
7
8
constexpr int times_2(const int x) {
    return 2 * x;
}

int main() {
    constexpr int x = times_2(1000);
    return x;
}

Here, x is explicitly marked as constexpr, and as expected, the compiler evaluates it at compile time, as seen on Godbolt. However, as Jason Turner points out in his C++ Weekly, this behavior isn’t guaranteed by the standard—it’s still just a maybe. Isn’t that surprising?

This realization led me to dive deeper into constexpr and its limitations. What exactly does it do, and when can we rely on it? Let’s explore!

constexpr functions may be evaluated during runtime

constexpr variables

limitations of constexpr static

This post is licensed under CC BY 4.0 by the author.