Reputation: 102346
I am trying to determine if std::call_once
works as expected under Visual Studio 2013 and below when C++11 is in effect. An example is shown below.
// C++ source file
std::once_flag flag;
int main()
{
std::call_once(flag, []() {
// ...
});
}
Microsoft's Support For C++11/14/17 Features does not appear to discuss std::call_once
. I am not sure if it depends upon Dynamic Initialization and Destruction with Concurrency or not. Though its a core language feature, Microsoft did not provide it until VS2015.
My question is, will std::call_once
work under most versions of Windows (XP and above) and most versions of Visual Studio with C++11 support (VS 2010 and above)? If not, then what are the requirements to use it?
Upvotes: 0
Views: 776
Reputation: 33754
this depend not from Visual Studio (this is only UI shell) but from which CRT version you use and are this implemented in CRT. if your code compiled and linked - implemented. call_once
declared in <mutex>
and internally call
int __CLRCALL_PURE_OR_CDECL _Execute_once(
once_flag& _Flag, _Lambda_fp_t _Lambda_fp, void *_Pv)
(from VC\crt\src\stl\xonce.cpp
) - this function call
BOOL WINAPI __crtInitOnceExecuteOnce(
__inout PINIT_ONCE InitOnce,
__in PINIT_ONCE_FN InitFn,
__inout_opt PVOID Parameter,
__out LPVOID* Context
);
which have equal signature as windows api InitOnceExecuteOnce
(available from Vista)
__crtInitOnceExecuteOnce
implementation (which will be embedded to your PE if you use static lib - libcpmt
or in dll like msvcp*.dll
if you use dynamic linkage CRT) - first look are kernel32.dll export InitOnceExecuteOnce
and if yes - simply call this api and exit. if it not exported (XP case) __crtInitOnceExecuteOnce
use yourself primitive implementation
(if several threads in concurrent call this api with same once_flag
- until "winner" thread will be do initialization (inside InitOnceCallback function (or lambda ) other threads will be wait in spin-lock loop with Sleep(0)
so this design for work in XP too and will be work
Upvotes: 2