In C++, I can implement lazy initialisation with static
:
struct foo { ... };
foo create_foo();
const foo& get_foo() {
static foo x = create_foo();
return x;
}
Here, initialisation occurs the first time get_foo
is called (lazy), get_foo
is guaranteed to be thread safe, and initialisation is guaranteed to only occur once. Specifically:
[stmt.dcl] "Dynamic initialization of a block-scope variable with static storage duration ... is performed the first time control passes through its declaration ... if control enters the declaration concurrently ... the concurrent execution shall wait for completion of the initialization"
How can I get the same behaviour in standard C?
In C, there are no references, and you have to type struct
, and you have to take care of initialization.
#include <stdbool.h>
struct foo { int a; };
struct foo create_foo();
const struct foo* get_foo() {
static bool initialized = false;
static struct foo x;
if (!initialized) {
initialized = true;
x = create_foo();
}
return &x;
}
To be thread-safe, you can use call_once
. Sadly, with a global variable.
#include <threads.h>
struct foo { int a; };
struct foo create_foo();
static struct foo global_x;
static void init_global_x(void) {
global_x = create_foo();
}
const struct foo* get_foo() {
static once_flag global_x_initialized = ONCE_FLAG_INIT;
call_once(&global_x_initialized , init_global_x);
return &global_x;
}