Article by Ayman Alheraki on March 28 2026 10:58 PM
constinit in C++20: Guaranteed Constant InitializationC++20 introduces a new keyword, constinit, to help developers safely initialize global or static variables. But it’s often misunderstood, so let’s break it down.
constinit?constinit is used to ensure a variable is initialized at compile-time or program startup, but unlike const or constexpr, the variable itself can still be modified later.
Think of it as a guarantee of initialization, not immutability.
Guarantees static initialization at compile-time (for global/static variables).
Can only be used on non-local variables (globals, namespace-scope, or static members).
The variable is not constant; you can change it after initialization.
Helps prevent the “static initialization order fiasco” in C++.
constinit vs const vs constexpr| Keyword | Compile-time Init | Can Modify Later | Notes |
|---|---|---|---|
const | Yes | No | Immutable after initialization |
constexpr | Yes | No | Must be compile-time constant |
constinit | Yes | Yes | Guarantees initialization, but mutable |
constinit does not make a variable constant. It just ensures it is initialized before use, especially important for global or static variables.
constinit int counter = 42; // Must be initialized at compile-time
int main() { std::cout << "Initial counter: " << counter << "\n";
// You can change it later counter += 8; std::cout << "Updated counter: " << counter << "\n";
return 0;}Output:
xxxxxxxxxxInitial counter: 42Updated counter: 50
Here,
constinitguarantees thatcounteris initialized at program startup. Later, we can still modify its value.
A common C++ issue is the static initialization order fiasco, where the order of global/static variable initialization across translation units is undefined. constinit helps catch errors at compile-time if a variable might not be safely initialized.
struct Config { int value;};
// Ensure this global config is initialized safelyconstinit Config globalConfig{ 10 };
int main() { std::cout << "Global config value: " << globalConfig.value << "\n"; globalConfig.value = 20; // Still mutable}Without constinit, you might accidentally write a static variable that depends on another static variable in another file, causing undefined behavior. constinit forces the compiler to check.
Cannot use constinit with local variables:
int main() { constinit int x = 5; // Error: constinit is for static/global variables only}Works with inline variables to ensure single initialization across multiple translation units.
Can be combined with constexpr but rarely needed, because constexpr already guarantees compile-time initialization.
constinit?Ensures safety for global and static variables.
Prevents subtle runtime bugs caused by uninitialized or misordered variables.
Still allows mutable behavior, unlike const.
In short:
constinit= “initialized correctly, but can change later.”