Given I want to improve my C++ code base. One step would be to mark functions as constexpr which fulfill the requirements of the used C++ standard. Is there a way to determine whether a function could be marked constexpr?
The only way I came up with is to add constexpr to a single instance, run the compiler, and check if it complains that it is not constexpr. Repeat until all instances are checked. This approach does not scale.
Related: Should we use constexpr everywhere we can?
In C++23, there are exactly two requirements for a constexpr function:
I would not be surprised if every single function in your code base satisfied this.
So you can mark every templated and inline function constexpr. Because constexpr functions are implicitly inline, you can't do this to extern functions.
This should mean every function definition in a header file can be constexpr.
(If you have compiler errors for constexpr functions that could never produce a constant expression, upgrade your compiler)
As there are more and more relaxations for constexpr, it's easier to ask:
Is there a way to detect functions that shouldn't be
constexpr?
The following functions should not be constexpr:
constexpr, but they would be unusable in constant expressions without the definition being availableconstexpr constructor
constexpr, but this constexpr would be misleadingthrow, goto, etc.)
constexpr since C++23, see P2448: Relaxing some constexpr restrictionsEvery other function (which in some code bases makes up the vast majority of functions) can be constexpr.
You could even automate this process using something like a clang-tidy rule.
It's more complicated in C++20 and older standards because there is the following rule:
For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression, or, for a constructor, an evaluated subexpression of the initialization full-expression of some constant-initialized object, the program is ill-formed, no diagnostic required.
- C++20 [dcl.constexpr] p6
This rule was dropped in the aforementioned proposal, but in C++20, it makes it harder to decide when to apply constexpr.
Proving automatically whether there exists a set of arguments that produces a constant expression is not easy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With