bpo-36876: Avoid static locals. by ericsnowcurrently · Pull Request #13372 · python/cpython
(...) The problem is how to initialize the global unique identifier in a safe way (thread safety / atomicity). But that could be implemented using "local static" variables.
I forgot to mention that "local static variables" would be easier to initialize properly, since they cannot be accessed before the function is called: before Python is initialized.
The case of global static variables is worse: we cannot statically initialize them, we need something to dynamically initialize them. Maybe at the first access?
About the global unique identifier, one solution would be to use the memory address of the variable: it should be unique. I don't see why a compiler would merge two variables.
Draft pseudo API:
void get_interpreter_specific(uintptr_t key, size_t size, void *value);
int set_interpreter_specific(uintptr_t key, size_t size, void *value);
#define PyStaticVariable(TYPE) static TYPE
// FIXME: add assertion to ensure that VAR is a PyStaticVariable
#define PyStaticVariable_get(VAR, VALUE) \
get_interpreter_specific((uintptr_t)&(VAR), sizeof(VAR), &(VALUE))
#define PyStaticVariable_set(VAR, VALUE) \
set_interpreter_specific((uintptr_t)&(VAR), sizeof(VAR), &(VALUE))
PyObject* func(void)
{
PyStaticVariable(int) var;
// if var doesn't exist in the interpreter local storage,
// its value is always 0 by default, for any type,
// as global static variables in C
int value;
PyStaticVariable_get(var, value);
value += 1;
if (PyStaticVariable_set(var, value) < 0) { return NULL; }
Py_RETURN_VALUE;
}
Problem: we cannot pre-allocate the storage of "var" value into the interpreter "local storage" hash table, so set_interpreter_specific() can fail with a memory allocation failure :-(