const and constexpr
Some values are set once and never change: the number of tries, a day's length in seconds, an exchange rate at startup. If such a variable is declared const, the compiler stops any accidental change to it:
int main() {
const int max_tries = 3;
max_tries = 5; // ✗
}error: cannot assign to variable 'max_tries' with const-qualified type 'const int'This is a compile error, not a warning: the program does not build until the extra assignment is removed.
Read-only variables
const before the type forbids changing the variable after initialization. That is why it must have an initial value: const int max_tries; does not compile either. The value itself can be anything, including one computed while the program runs:
#include <iostream>
int main() {
int width = 4;
const int area = width * width;
width = 5;
std::cout << area << ' ' << width << '\n'; // 16 5
}area got its value at initialization and kept it when width changed. const belongs to the variable, not to the value. A copy of a const variable is an ordinary variable, and it can change. const helps the reader too: the value of such a variable is set in one place, the declaration.
Values at compile time
constexpr demands more: the value must be known at compile time. So such a variable is initialized with a constant—for example, a literal or an expression of literals and other constexpr variables. A const variable whose value is computed at run time, like area above, does not qualify. The compiler computes that expression itself, and the program gets the computed result:
#include <iostream>
int main() {
constexpr int kSecondsPerHour = 60 * 60;
constexpr int kSecondsPerDay = 24 * kSecondsPerHour;
std::cout << kSecondsPerDay << '\n'; // 86400
}A constexpr variable cannot be changed either: constexpr includes const. If a value is known in advance, declare the variable constexpr; if it appears only while the program runs, declare it const. In this course, constexpr constants are named in the kName style, while const variables get ordinary names.
Common mistake
A constexpr variable is initialized with a value that is known only while the program runs:
int main() {
int width = 4;
constexpr int area = width * width; // ✗
return area;
}error: constexpr variable 'area' must be initialized by a constant expressionwidth is an ordinary variable. The 4 is written right in the code, but the variable can change, so its value is not a constant. Declare area as const: a value computed at run time is enough for it. Another way is to make width itself constexpr: then width * width is known at compile time.