Background
C++ originally only supported macros (#define) and constants (const). However, this was insufficient for defining values at compile time. In C++11, the constexpr keyword was introduced, allowing values to be computed during compilation rather than just at runtime.
Problem
Before constexpr, many tasks had to be solved using either macros (a crude text substitution without type safety) or const, which did not always guarantee that an expression would be executed at compile time. This complicated program optimization and resulted in less predictable behavior.
Solution
constexpr guarantees the compiler that the declared expression will be evaluated at compile time if possible. It is used to declare functions, variables, and even constructors and methods of classes that can be safely and efficiently computed at compile time.
Code example:
constexpr int Square(int x) { return x * x; } constexpr int size = Square(5); // size is computed at compile time const int arr[size] = {}; // can be used as array size
Key features:
Can any function be used as constexpr?
No. The function must meet a number of restrictions: it should be simple enough, contain a single return statement (before C++14), or only constant-evaluated code (from C++14 onward).
constexpr int f(int x) { return x + 2; } // ok constexpr int g(int x) { int y = x + 2; return y; } // before C++14: does not compile! after — it's allowed
Can all constexpr variables be computed at compile time?
No. If a non-constant value is used during initialization or the expression cannot be evaluated at compile time, there will be an error.
int val; // constexpr int x = f(val); // Error: val is not initialized!
What is the difference between constexpr and const?
const only guarantees that it cannot be modified, but does not guarantee computation at compile time. constexpr requires that the value be computed at compile time (if possible).
const int x = time(nullptr); // ok, but computed at runtime constexpr int y = 42; // ok, computed at compile time
A developer uses #define PI 3.14 for all circle area calculations.
Pros:
Cons:
A developer uses constexpr double PI = 3.141592653589793; and template constexpr functions for calculations.
Pros:
Cons: