Given the following code:
#include <iostream> template <std::size_t N> struct foo { static std::size_t value; }; template <> std::size_t foo<0>::value = 0u; template <size_t N> std::size_t foo<N>::value = 1u + foo<N - 1u>::value; int main() { std::cout << foo<3u>::value << ' ' << foo<2u>::value << ' ' << foo<1u>::value << ' ' << foo<0u>::value << std::endl; }
where the static member value
of the template struct foo
is recursively initialized, I get different outputs from g++:
3 2 1 0
and from clang++:
1 1 1 0
So seem that g++ initializes foo<N>::value
recursively using the initialized value of foo<N-1u>::value
where clang++ uses zero for foo<N-1u>::value
.
Two questions:
question. The difference between static initialization and dynamic initialization: A static initialization in java is a particular block that is made to run before the main () method in java whereas dynamic initialization refers to the initiation of the project during the rum time.
Static Initialization: Here, the variable is assigned a value in advance. This variable then acts as a constant. Dynamic Initialization: Here, the variable is assigned a value at the run time. The value of this variable can be altered every time the program is being run.
C++ guarantees that variables in a compilation unit (. cpp file) are initialised in order of declaration. For number of compilation units this rule works for each one separately (I mean static variables outside of classes). But, the order of initialization of variables, is undefined across different compilation units.
We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value.
In C, static and global variables are initialized by the compiler itself. Therefore, they must be initialized with a constant value. Note that the above programs compile and run fine in C++, and produce the output as 10. As an exercise, predict the output of following program in both C and C++. This article is contributed by Shankar Shastri.
Let us look at the tracing and see how static variables are handled in a recursive function. First, the function fun is called for the value 5 & 5 is greater than 0. Yes, so it will increment the x value i.e. x becomes 1, and then it calls itself with the reduced value of n i.e. 4, and x will be added at returning time.
Modern compilers Clang, MSVC detect it with the right use of right warning flags. The reason for this language design decision is to ensure there is a unique order to destroy members; otherwise, the destructor would have to destroy objects in different orders, depending on the constructor that built the object.
This code harbors a bug that’s as subtly harmful as it is hard to spot hence Write member initializers in the same order as their declaration Many compilers (but not all) will issue a warning if you break this rule. Modern compilers Clang, MSVC detect it with the right use of right warning flags.
It is unspecified. Both compilers are right.
Here are the relevant pieces from cppreference "initialization".
For all other non-local static and thread-local variables, Zero initialization takes place
So for all these variables, they are zero when the program loads. Then:
After all static initialization is completed, dynamic initialization of non-local variables occurs in the following situations:
1) Unordered dynamic initialization, which applies only to (static/thread-local) class template static data members and ... that aren't explicitly specialized.
And these variables match the criteria. And then it says:
Initialization of such static variables is indeterminately sequenced with respect to all other dynamic initialization ....
Which means that any sequence of initialization is fine. Both compilers are correct.
To avoid the issue use constexpr
to force a "constant initialization" instead.
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