static void func1(){
static int i(9);
};
Is memory allocated for the static variable i when the function is called or when the program starts?
For that particular case, it's up to the implementation. First, the allocation question.
It's true that the standard states that static storage duration variables are initialised as a consequence of program initiation. See, for example C++17 [basic.static.start]:
(1) Variables with static storage duration are initialized as a consequence of program initiation.
That would seem to indicate that memory must be allocated before main even starts. However, C++ (like C) also follows the "as-if" rule, which states that:
... an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
So, since i is clearly not accessible from outside your function, creation of the variable can be deferred until that point. Actually, since i is never used even within the function (and because it's a basic type with trivial constructor or destructor), it can actually be deferred forever and optimised out of existence :-)
Next, initialisation. The afore-mentioned standards link makes a distinction between initialisation with a constant and non-constant expression. The latter, dynamic initialisation, is required to be done at the point when you first reach the declaration, as it may depend on the current state of other program variables used to initialise it.
However, since you're using the constant 9 to initialise your integer (and that 9 will not change at any point during program execution), that clearly falls under the constant initialiser parts of the standard. In that case, the variable just has to be bought into existence and initialised before use, so can be done at any point between program initiation and initial declaration.
This is covered by the text:
(3) An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that (3.1) the dynamic version of the initialization does not change the value of any other object of static or thread storage duration prior to its initialization; and (3.2) the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically.
The bottom line is probably that you should be thinking less about the underlying mechanisms of the implementation and instead concentrate just on what the standard mandates.
In this particular case, it makes no difference whatsoever whether allocation and/or initialisation happens before main or upon first encountering the declaration. That's likely to be different once you start having non-trivial constructors or destructors, but not in this case.
Memory for the static variable is allocated when the program starts but the variable is not initialized until the function gets called the first time.
c++17 [basic.start.static] /2 and /3. Because this is a constant-based initialisation, it happens (or is allowed to happen) long before the code is run. Only for dynamic initialisations must the initialisation be deferred.static variables, not for static variables in functions.