constexpr Functions: Optimization vs Guarantee -- Andreas Fertig
Constexpr has been around for a while now, but many don’t fully understand its subtleties. Andreas Fertig explores its use and when a constexpr expression might not be evaluated at compile time.
constexpr Functions: Optimization vs Guarantee
by Andreas Fertig
From the article:
The feature of constant evaluation is nothing new in 2023. You have constexpr available since C++11. Yet, in many of my classes, I see that people still struggle with
constexprfunctions. Let me shed some light on them.What you get is not what you see
One thing, which is a feature, is that
constexprfunctions can be evaluated at compile-time, but they can run at run-time as well. That evaluation at compile-time requires all values known at compile-time is reasonable. But I often see that the assumption is once all values for aconstexprfunction are known at compile-time, the function will be evaluated at compile-time.I can say that I find this assumption reasonable, and discovering the truth isn’t easy. Let’s consider an example (Listing 1).
constexpr auto Fun(int v) { return 42 / v; ① } int main() { const auto f = Fun(6); ② return f; ③ }Listing 1 The
constexprfunctionFundivides 42 by a value provided by the parameterv①. In ②, I callFunwith the value6and assign the result to the variablef.Last, in ③, I return the value of
fto prevent the compiler optimizes this program away. If you use Compiler Explorer to look at the resulting assembly, GCC with-O1brings this down to:main: mov eax, 7 retAs you can see, the compiler has evaluated the result of 42 / 6, which, of course, is 7. Aside from the final number, there is also no trace at all of the function
Fun.Now, this is what, in my experience, makes people believe that
Funwas evaluated at compile-time thanks toconstexpr. Yet this view is incorrect. You are looking at compiler optimization, something different fromconstexprfunctions.

C++’s undefined behaviour impacts safety. Sandor Dargo explains how and why uninitialised reads will become erroneous behaviour in C++26, rather than being undefined behaviour.
In the December issue of Overload [
Integer division is one of the most expensive operations in C++, but when the divisor is known at compile time, the compiler can optimize it significantly. This post explores different approaches—using templates, lambda expressions, and template metaprogramming—to speed up division while maintaining clean and efficient code.
Bjarne Stroustrup, creator of C++, is advocating for the adoption of guideline-enforcing profiles to enhance the language's safety and security.
In this article, we’ll see details of