--- title: std::call_once bug in Visual Studio 2012/2013 layout: post excerpt: >
In this post, I will describe a neat bug I've stumbled upon in C++ Standard Library implementation shipped with Microsoft Visual Studio 2012/2013.
--- ### Abstract In this post, I will describe a neat bug I've stumbled upon in C++ Standard Library implementation shipped with Microsoft Visual Studio 2012/2013. ### Licensing This post, including code samples, is licenced under the terms of the MIT License. See [LICENSE.txt](https://github.com/egor-tensin/cpp_tips/blob/gh-pages/LICENSE.txt) for details. ## Introduction I've recently come across a nasty standard library bug in the implementation shipped with Microsoft Visual Studio 2012/2013. [StackOverflow](https://stackoverflow.com) was of [no help](https://stackoverflow.com/questions/26477070/concurrent-stdcall-once-calls), so I had to somehow report the bug to the maintainers. Oddly enough, Visual Studio's [Connect page](https://connect.microsoft.com/VisualStudio) wouldn't let me to report one, complaining that I supposedly had no right to do so, even though I was logged in from my work account, associated with my Visual Studio 2013 installation. Fortunately, I've come across the personal website of this amazing guy, [Stephan T. Lavavej](http://nuwen.net/stl.html), who appears to be the chief maintainer of Microsoft's standard library implementation. He seems to be your go-to guy when it comes to standard library misbehaviour. ## C++11 and singletons Anyway, I was designing a software system with a couple of singletons in it. I was trying to do proper singletons using C++11 like this: {% highlight c++ %} #include
The point is that the Logger::get_instance
routine above wasn't
thread-safe until C++11.
Imagine what might happen if Logger
s constructor takes some time to
initialize the instance.
If a couple of threads then call get_instance
, the first thread
might begin the initialization process, making the other thread believe that it
doesn't need to initialize the instance anymore (goodbye, C++03).
The second thread might then return a reference to a not fully initialized (and
hence, unsafe to use) instance.
Since C++11 includes the proposal for
"Dynamic Initialization and Destruction with Concurrency"
mentioned above, this routine would indeed be thread-safe in C++11.
Unfortunately, the compilers shipped with Visual Studio 2012/2013 didn't
implement this particular proposal, which caused me to turn my eyes to
std::call_once
, which seemed to implement exactly what I
wanted.