Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I always replace 'const int' with 'constexpr int' in C++11 whenever possible?

Would you replace

const int one = 1;
const int two = 2;

with this?

constexpr int one = 1;
constexpr int two = 2;

Is my understanding correct that both blocks are semantically identical and that it is currently merely a matter of taste?

On the other hand, as constexpr implies const, you could argue that it is more consistent to always prefer the more restrictive form, even in trivial situations where it does not make a difference?

(I understand that the situation completely changes when the expression on the right side are allowed to be more complicated. So for clarification, the question only focuses on the most simple case where the expression is a fixed integer number.)

like image 705
Philipp Claßen Avatar asked Feb 25 '13 23:02

Philipp Claßen


People also ask

Should I use const with constexpr?

Use constexpr if the value of your variable is known at compile time. Use const in cases where the value is not known at compile time, or you can't use constexpr with the type even though you know it at compile time. In C++17, constexpr is not available for all types such as string.

Should you use constexpr everywhere?

Yes. I believe putting such const ness is always a good practice wherever you can. For example in your class if a given method is not modifying any member then you always tend to put a const keyword in the end.

Why should we use constexpr?

The primary usage of constexpr is to declare intent. If an entity isn't marked as constexpr - it was never intended to be used in a constant-expression; and even if it is, we rely on the compiler to diagnose such context (because it disregards our intent).

Why is constexpr over const?

const can only be used with non-static member function whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.


1 Answers

I think your statement saying that const and constexpr "are semantically identical" should be revised: they both declare objects whose value cannot change, but constexpr also requires the initializer expression to be computable at compile-time.

Now if the expression on the right-hand side cannot be computed at compile-time, using constexpr is out of the question. On the other hand, as long as the initializer is a literal, you could use constexpr, but keep into account what the semantics of your variable is: does your constant variable really represent something whose value should be computable at compile-time?

In a SW maintenance/evolution optics, it is possible that you will change the way you initialize your variable throughout time: today the initializer is a literal, tomorrow it might be a more complex expression.

Regardless of the way you are assigning it a value now, do you think that i will ever need to be initialized by anything else than a literal, and that the initializing expression may not be computable at compile-time? If that is the case, then just make your variable const, even though you are currently initializing it with a literal; otherwise, make it constexpr.

In other words, choose the qualifier that best expresses the semantics of your variable.

like image 77
Andy Prowl Avatar answered Oct 18 '22 18:10

Andy Prowl