Let's consider this hunk of code that simply tries to initialize a map from a constexpr array:
#include <string>
#include <map>
#include <array>
#include <tuple>
constexpr std::array<std::pair<int, const char *>, 10> my_array {
{ { 0, "dd" },
{ 1, "dd" },
{ 2, "dd" },
{ 7, "dd" },
{ 8, "dd" },
{ 9, "dd" }}
};
std::map<int, std::string> my_map(std::begin(my_array), std::end(my_array));
int main() {
return my_map[0].size(); //dummy random operation
}
I know there is not way to predict initialization order for the two variables (my_array and my_map). That said, my_array is constexpr, thus should be available a compile time, thus there should be no "initialization order" problem at startup.
Is this code correct or does the initialization order problem remains?
constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.
The short answer is that not only is static useful, it is pretty well always going to be desired. First, note that static and constexpr are completely independent of each other. static defines the object's lifetime during execution; constexpr specifies that the object should be available during compilation.
A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.
Pretty much redundant; constexpr variables have internal linkage per default.
[basic.start.static/2]:
Constant initialization is performed if a variable or temporary object with static or thread storage duration is constant-initialized. [...] Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. All static initialization strongly happens before ([intro.races]) any dynamic initialization.
So, "Is this code correct?": Yes, as my_array
is constant initialized, and this happens before dynamic initialization (my_map
).
(This quote is from the current draft standard, but this rule exists for C++14 as well)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With