If an object is declared const
, its value is guaranteed to be available only at runtime, but if it's declared constexpr
, the value is guaranteed to be available both during compilation and at runtime. So if I have an object whose value is available during compilation, are there any situations where I should not declare it constexpr
?
const int magicValue = 42; // Does this ever make sense
// (using const instead of constexpr)?
For functions, if a function can return a value computed during compilation when passed arguments with values available during compilation, would it ever make sense to not declare the function constexpr
?
struct Point { int x; int y; };
Point midPoint(Point p1, Point p2) // Does this ever make
{ // sense (not declaring
return { (p1.x + p2.x) / 2 , (p1.y + p2.y) / 2 }; // the function
} // constexpr)?
The only case I can conceive of is when you don't want to commit to the function being able to compute a compile-time constant when called with known-at-compile-time arguments, e.g., if you want to preserve the flexibility to change midPoint
's implementation without changing its interface (thus potentially breaking callers). For example, you might want to preserve the flexibility to add non-constexpr
side-effects to midPoint
, e.g., IO.
For variables, I don't see any reason not to use constexpr
when you can. But it's not always possible to do so, e.g. when the initializer of a variable is computed by a virtual function e.g.
Adding constexpr
to a function is an interface change: you are expressing the fact that you can use it to initialize constexpr
variables. This imposes constraints on the implementation of your function, such as no calling of virtual functions, no dynamic memory allocations and no lambda functions as function objects.
Note that the resolution to LWG issue 2013 does not allow implementers of the Standard Library the freedom to add constexpr
to library functions. One of the reasons is that declaring a function constexpr
can inhibit certain debugging implementations that do dynamic allocations (notably iterator checking). This means that future expansions of constexpr
to the Standard Library need to be separate proposals. This is in contrast to noexcept
, where library writers have more freedom.
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