Initialization of a static variable with a variable value

From the book of the C-2 century:

Static variables, even those inside the function, are initialized when the program starts, before the main one, so you cannot initialize them with a variable value.

//this fails: can't call gsl_vector_alloc() before main() starts static gsl_vector *scratch = gsl_vector_alloc(20); 

This is annoying, but easy to solve with a macro to start from scratch and highlight on first use:

 #define Staticdef(type, var, initialization) \ static type var = 0; \ if (!(var)) var = (initialization); //usage: Staticdef(gsl_vector*, scratch, gsl_vector_alloc(20)); 

I don’t understand what difference the macro made. Does this not do the same after preprocessing?


+6
source share
2 answers

Does he do the same after preprocessing?

No, both do not necessarily behave the same.

This initialization is guaranteed to work only once :

 static int i = 42; /* Initialisation */ 

This appointment

 static int i = 0; if (!i) /* line X */ i = 42; /* Assignment */ 

no, because each time the program stream reaches line X and i is 0 , then i set to 42 (again).

Examples:

 #include <stdio.h> void foo(int inew) { static int i = 42; printf("%d\n", i); i = inew; } void bar(int inew) { static int i = 0; if (!i) i = 42; printf("%d\n", i); i = inew; } int main(void) { foo(43); foo(0); foo(44); printf("\n"); bar(43); bar(0); bar(44); return 0; } 

Run it and see the difference:

 42 43 0 42 43 42 
+6
source

The preprocessor replaces only the text, so the final result is a Staticdef macro:

 static gsl_vector *scratch = 0 ; if (!(scratch )) scratch = (gsl_vector_alloc(20)); 

You can enter this yourself if you want or use a macro.

This, of course, is different from the wrong version:

 static gsl_vector *scratch = gsl_vector_alloc(20); 

I recommend not using a macro, since it cannot be wrapped in do {} while, and only obfuscates the code.

+3
source

Source: https://habr.com/ru/post/977656/


All Articles