Difference Between Initialization of Static Variables in C and C++

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



Leave a reply



Submit