on first look task is very simply, can be next code:
void func()
{
static LONG first = TRUE;
if (_InterlockedExchange(&first, FALSE))
{
subfunc();
}
// some code
}
this give 100% guarantee that subfunc() will be called once and only once even if several thread in concurrent call your func()
but what be if // some code depended on result of subfunc ? in this case task become already not trivial. need some synchronization. and here already depended from os or compiler. in Windows, begin from Vista understand this problem and add function InitOnceExecuteOnce - read Using One-Time Initialization
if your subfunc() have no in and out parameters code can be very simply:
BOOL CALLBACK InitOnceCallback(PINIT_ONCE /*InitOnce*/, PVOID /*Parameter*/,PVOID* /*Context*/)
{
subfunc();
return TRUE;
}
void func()
{
static INIT_ONCE once = RTL_RUN_ONCE_INIT;
if (InitOnceExecuteOnce(&once, InitOnceCallback, 0, 0))
{
// somecode
}
// error init
}
also some modern compilers can correct handle static one time initialization. say latest versions of CL. with it code can be next:
void func()
{
static char tag = (subfunc(), 0);
// some code
}
here CL internally call special functions (implemented in CRT) _Init_thread_header, _Init_thread_footer - implementation can be look in crt source code - thread_safe_statics.cpp