Static and dynamic initialization describes the process of loading a binary file and moving to the point when main is ready to go.
static initialization describes the information that the compiler can execute at compile time, and allows you to fix the values ββin binary format, so when the binary is loaded by the operating system, it has the correct value.
dynamic initialization describes code that is inserted by the compiler before the main starts, which initializes information that the compiler could not calculate. This may be due to the fact that it is directly related to the code or that it refers to information that was not visible to the compiler at compile time.
But what if a and b had an automatic storage duration
The simple case when a is an automatic variable of a bounded domain.
int a = 12;
This cannot be statically initialized because the compiler will not know where to initialize a, since it will be different every time, and from every thread that called it.
The compiler will be able to initialize with something like.
mov (_addr_of_a), 12
Since _addr_of_a is unknown before execution, and the value 12 is embedded in the code, the case of static initialization will not be executed.
More complicated cases ...
int a[] = { };
Perhaps this will be implemented by the compiler as a mixture of static and dynamic code, as shown below.
static int a_init = { }; memcpy( a, a_init, length_in_bytes_of_a );
So in some cases there will be a "leak" from static initialization at runtime.
Dynamic behavior is more problematic - it assumes that a function that usually does not expose its implementation has both slow execution time and constexpr in order to give importance to caching at the beginning of the result. I have not seen this optimization happen.
Static and dynamic initialization are technical terms that describe the process of creating a running program. Similar patterns may exist for local variables, but they will not fall into the technical definition of static and dynamic initialization.