Last updated:2026-10-12
The Complete C++ const Family¶
Outline
- const
- constexpr
- C++20
- consteval
- constinit
Note: all code examples in this article have been posted to the Knowledge Planet.
1. const¶
const is one of the earliest keywords we meet when learning C++/C. It is usually used as a cv-qualifier to indicate that an object is immutable. It does not guarantee compile-time evaluation; when exactly the evaluation happens is up to the compiler. For example:
const can sometimes be used in compile-time constant expressions, but there are exceptions, for example:
const double count_1 = 3.3;
std::array<double, static_cast<int>(count_1)> moreDoubles1 {1.1, 2.2, 3.3};
This produces an error: the value of 'count_1' is not usable in a constant expression
But this is fine:
The essence is compile-time expression evaluation, and so C++11 introduced constexpr.
2. constexpr¶
constexpr can be used to specify that a variable's value may appear in a constant expression; here we only need to change const to constexpr in the earlier example for it to work.
constexpr double count_2 = 3.3;
std::array<double, static_cast<int>(count_2)> moreDoubles2 {1.1, 2.2, 3.3};
constexpr does not necessarily execute only at compile time. Its essential meaning is that it can be computed at compile time, but if a constexpr variable or function is used at run time, it can also execute at run time.
For example, result1 and result2 are completely different: result1 is computed at compile time, while result2 is computed at run time. A question to leave you with: do you know why?
So a function specified as constexpr is not necessarily computed at compile time.
constexpr int compileTimeSum(int a, int b) {
return a + b;
}
int main() {
constexpr int result1 = compileTimeSum(3, 5);
int x = 10;
int result2 = compileTimeSum(x, 20);
return 0;
}
Then who can guarantee that? Along comes C++20.
3. C++20¶
3.1 consteval¶
consteval solves the problem above: it can only be used on functions and forces every call to happen at compile time. If we now change constexpr to consteval above, what happens to result2?
It errors out: call to consteval function 'compileTimeSum(x, 20)' is not a constant expression
consteval int compileTimeSum(int a, int b) {
return a + b;
}
int main() {
constexpr int result1 = compileTimeSum(3, 5);
int x = 10;
int result2 = compileTimeSum(x, 20);
return 0;
}
If consteval is used on a variable, it also errors: error: a variable cannot be declared 'consteval'.
3.2 constinit¶
constinit forces static or thread-local variables to undergo constant initialization.
- Cannot be used together with constexpr or consteval
- A non-type specifier whose role is that of an assert
- Guarantees that the variable is statically initialized
- Can only be used with static or thread_local
For example, the following fails to compile: error: 'constinit' can only be applied to a variable with static or thread storage duration
constinit int a = 100;
int main() {
++a;
constinit auto b = 100; // error
// b has thread storage duration
constinit thread_local auto b = 100;
}
Related Topics¶
- C++ Pure Virtual Functions and Abstract Classes | C++那些事
- C++ assert | C++那些事
- C++ Bit Fields | C++那些事
- Implementing C++ Polymorphism in C | C++那些事
- C++ const Constants and Qualifiers | C++那些事
- C++ Dereference Operator * | C++那些事
- C++ Initialization and Assignment | C++那些事
- Ways to Return Multiple Values in C++ | C++那些事
- C++ mutable Keyword | C++那些事
- C++ restrict and Compiler Optimization | C++那些事