From 21st century C book:
Static variables, even those inside of a function, are initialized when the program starts, before main, so you can’t initialize them with a nonconstant value.
//this fails: can't call gsl_vector_alloc() before main() starts static gsl_vector *scratch = gsl_vector_alloc(20);
This is an annoyance, but easily solved with a macro to start at zero and allocate 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. Doesn't it do exactly the same thing after preprocessing?
Doesn't it do exactly the same thing after preprocessing?
No, both not necessarily behave the same.
This initalisation is guaranteed to run only once:
static int i = 42; /* Initialisation */
This assignment
static int i = 0;
if (!i) /* line X */
i = 42; /* Assignment */
is not, as everytime the program flow reaches line X and i
equals 0
then i
is 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
Preprocessor only replaces the text, so that the end result of Staticdef
macro is:
static gsl_vector *scratch = 0 ;
if (!(scratch )) scratch = (gsl_vector_alloc(20));
You can type that yourself if you wish or use the macro.
This is of course different than the incorrect version:
static gsl_vector *scratch = gsl_vector_alloc(20);
I recommend not using the macro as it cannot be wrapped in a do{}while, and only obfuscates the code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With