I discussed this in a follow-up to the blog post referenced in the question. If for some reason you can't use boost::call_once
your block-scoped static is a pointer, POD, or has a thread-safe constructor, you can write the same initialization guard code that GCC would emit:
// Define a static local variable once, safely, for MSVC
//
// This macro is necessary because MSVC pre-2013 doesn't
// properly implement C++11 static local initialization.
// It is equivalent to writing something like
//
// static type var = stmt;
//
// in a compliant compiler (e.g. GCC since who knows when)
// States for lock checking
enum { uninitialized = 0, initializing, initialized };
// Preprocessor hackery for anonymous variables
#define PASTE_IMPL(x, y) x ## y
#define PASTE(x, y) PASTE_IMPL(x, y)
#define ANON_VAR(var) PASTE(var, __LINE__)
#define STATIC_DEFINE_ONCE(type, var, stmt) \
static type var; \
static int ANON_VAR(state); \
bool ANON_VAR(cont) = true; \
while (ANON_VAR(cont)) { \
switch (InterlockedCompareExchange(&ANON_VAR(state), \
initializing, uninitialized)) { \
case uninitialized: \
var = stmt; \
InterlockedExchange(&ANON_VAR(state), initialized); \
ANON_VAR(cont) = false; \
break; \
case initializing: \
continue; \
case initialized: \
ANON_VAR(cont) = false; \
break; \
} \
} do { } while (0)
You can use this like
void concurrently_accessed() {
STATIC_DEFINE_ONCE(int, local_var, thread_unsafe_initializer());
// ...
}
This approach takes advantage of zero-initialization of static block-scoped variables, which is required by the C language standard. The above macros will let you safely use "magic" statics until actual compiler & run-time support arrive in MSVC 2014.