The point is probably to allow stuff like
singleton& get_instance(){ static volatile singleton* instance; static mutex instance_mutex; if (!instance) { raii_lock lock(instance_mutex); if (!instance) instance = new singleton; } return *instance;}
which would break if instance
was written to before initialization was complete. With MSVC semantics, you are guaranteed that as soon as you see instance != 0
, the object has finished being initialized (which is not the case without proper barrier semantics, even with traditional volatile semantics).
This double-checked lock (anti-)pattern is quite common actually, and broken if you don't provide barrier semantics. However, if there are guarantees that accesses to volatile
variables are acquire + release barriers, then it works.
Don't rely on such custom semantics of volatile
though. I suspect this has been introduced not to break existing codebases. In any way, don't write locks according to MSDN example. It probably doesn't work (I doubt you can write a lock using just a barrier: you need atomic operations -- CAS, TAS, etc -- for that).
The only portable way to write the double-checked lock pattern is to use C++0x, which provides a suitable memory model, and explicit barriers.