Difference between initialization of static variables in C and C++
It compiles in C++ because C++ needs to support dynamic initialization anyway, or you couldn't have local static or non-local objects with non-trivial constructors.
So since C++ has this complexity anyway, supporting that initialization like you show isn't complicated to add anymore.
In C that would be a big matter because C doesn't have any other reason to support initialization done at program startup (apart from trivial zero initialization). In C, initial values of file-scope or local static objects can always statically be put into the executable image.
Difference between C and C++ static initialization
C++ compiler generates an additional 'Start' function, where all "global function calls" are executed before the PC (program counter) is set to the address of 'main'.
A "global function call" is any function-call which is performed in order to initialize a global object (including implicit function calls, i.e., constructors).
C compiler does not generate such 'Start' function, and the PC is set to 'main' as soon as the OS loads the executable and runs the process.
C static variables initialization
This (statics/globals) is where an initializing definition is really different from an uninitialized definition followed by an assignment.
Historically, the former even used to have different syntax (int count /*no '=' here*/ 0;
).
When you do:
int fun() {
static int count = 0;
//...
}
then except for the different scopes (but not lifetimes) of count
, it's equivalent to:
static int count = 0; //wider scope, same lifetime
int fun() {
//...
}
In both cases, the static variable becomes initialized at load time, typically en-masse with other statics and globals in the executable.
C static variables and initialization
There is a nice answer here:
Just a short excerpt:
First of all in ISO C (ANSI C), all static and global variables must be initialized before the program starts. If the programmer didn't do this explicitly, then the compiler must set them to zero. If the compiler doesn't do this, it doesn't follow ISO C. Exactly how the variables are initialized is however unspecified by the standard.
What happens to initialization of static variable inside a function
Although the standard does not dictate how compilers must implement behavior, most compilers do a much less sophisticated thing: they place c
into static memory segment, and tell the loader to place zero into c
's address. This way f
comes straight to pre-initialized c
, and proceeds to printing and incrementing as if the declaration line where not there.
In C++ it optionally adds code to initialize c
to static initialization function, which initializes all static variables. In this case, no call is required.
In essence, this amounts to c
starting its lifetime before the first call to f
. You can think of c
's behavior as if it were a static
variable outside f()
with its visibility constrained to f()
's scope.
The initialization of static variables in C
Yes, all members are initialized for objects with static storage. See 6.7.8/10 in the C99 Standard (PDF document)
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.
To initialize everything in an object, whether it's static
or not, to 0, I like to use the universal zero initializer
sometype identifier0 = {0};
someothertype identifier1[SOMESIZE] = {0};
anytype identifier2[SIZE1][SIZE2][SIZE3] = {0};
There is no partial initialization in C. An object either is fully initialized (to 0
of the right kind in the absence of a different value) or not initialized at all.
If you want partial initialization, you can't initialize to begin with.
int a[2]; // uninitialized
int b[2] = {42}; // b[0] == 42; b[1] == 0;
a[0] = -1; // reading a[1] invokes UB
Related Topics
Same Random Numbers Every Time I Run the Program
How to Ensure That the Template Parameter Is a Subtype of a Desired Type
Uses for Negative Zero Floating Point Value
How to Use Setenv() to Export a Variable in C++
Thread Safety of Std::Map for Read-Only Operations
C++ Comparison of Two Double Values Not Working Properly
Does "Undefined Behaviour" Extend to Compile-Time
Catching "Stack Overflow" Exceptions in Recursive C++ Functions
Link .So File to .Cpp File via G++ Compiling
How to Get the Mouse Position in a Console Program
Why Is the Size of Array as a Constant Variable Not Allowed in C But Allowed in C++
Create a Reverse Linkedlist in C++ from a Given Linkedlist
Why Do String Literals (Char*) in C++ Have to Be Constants
_Iterator_Debug_Level Value '0' Doesn't Match Value '2'
Cast Vector<T> to Vector<Const T>
Why, Really, Deleting an Incomplete Type Is Undefined Behaviour