C++ 20 Addition : constinit specifier

Sohini Dhar
3 min readJan 14, 2022
C++ 20 : constinit specifier

Yesterday, I was watching a Back to Basics lecture series from CppCon 2021 by Rainer Grimm titled “Back to Basics: const and constexpr”. In the series, he explained the various uses of const in C++:

1. const (introduced in C++98)
2. const_cast (C++98)
3. constexpr (C++11)
4. consteval (C++20)
5. constinit (C++20)
6. std::is_constant_evaluated (C++20)

On watching the whole video, you will get a very good idea on the differences between all these features, so I would not dive into the details of all of them. One feature among them which really got my attention was the constinit specifier introduced in C++ 20. This specifier is used to “declare a variable with static or thread storage duration”. This specifier solves the problem of static initialization order fiasco.

What is “Static Initialization Order Fiasco” ?

If we have two files containing static member variables, one static variable being dependent on the other, the code can show different behaviour depending on the linking of the files. To understand the above line, let us look at the following piece of code:

fileA.cpp

int areaOfRect(int length, int breadth)
{
return (length*breadth);
}
auto staticA = areaOfRect(3,4);

main.cpp

#include <iostream>extern int staticA;
auto staticB = staticA;
int main()
{
std::cout << "Static B: " << staticB << std::endl;
return 0;
}

While compiling, if we give the following commands:

1. g++ -c fileA.cpp
2. g++ -c main.cpp
3. g++ main.o fileA.o -o mainFile
4. g++ fileA.o main.o -o fileMain

On executing the mainFile, we have the output as:

staticB = 0

On executing the fileMain, we have the output as:

staticB = 12

So, you see the behaviour is different based on the linking of the files, this is the problem of “Static Initialization Order Fiasco”. It can be solved effectively using constinit specifier.

How can we solve the problem of “Static Initialization Order Fiasco” ?

Adding the specifier constinit along with the static variables will solve our problem. The above pieces of code will then be modified to:

fileA.cpp

constexpr int areaOfRect(int length, int breadth)
{
return (length*breadth);
}
constinit auto staticA = areaOfRect(3,4);

main.cpp

#include <iostream>extern constinit int staticA;
auto staticB = staticA;
int main()
{
std::cout << "Static B: " << staticB << std::endl;
return 0;
}

While compiling, if we give the following commands:

1. g++ -std=c++20 -c fileA.cpp
2. g++ -std=c++20 -c main.cpp
3. g++ main.o fileA.o -o mainFile
4. g++ fileA.o main.o -o fileMain

On executing the mainFile, we have the output as:

staticB = 12

On executing the fileMain, we have the output as:

staticB = 12

No matter how the files are linked, we will always get the same output.

This feature was very interesting for me to learn and so I thought I could share this example and explain the same to everyone.

In case you know about more advantages of constinit please do let me know too. In case you find the article interesting, please do not forget to leave your comments. All constructive criticism are welcome. I am just a beginner in C++ and would love to know from all the wizards of C++ out there.

Thanks! Happy C++ Coding!Please follow, like, comment, share if you like this.

--

--