In the Boost 1.5.1 source under smart_ptr\detail\atomic_count_win32.hpp is a neat little atomic reference counter boost::detail::atomic_count.
on line 48, they do a cast I’m curious about:
class atomic_count
{
public:
// ...
operator long() const
{
return static_cast<long const volatile &>( value_ );
}
private:
long value_;
Why is the counter value cast to a-reference-to-a-volatile-constant-long (long const volatile&)?
MSVC provides a now-deprecated extension on
volatilevariables, giving them acquire and release semantics (memory ordering guarantees, with respect to multithreaded programming.)This cast “enables” this extension on the variable, giving it read-acquire semantics (to match any release-writes that may also occur). Again, this is, non-standard. In C++11 code you should use
std::atomic<>.They need this because
boost::shared_ptrgives guarantees of correctness forshared_ptr<T>in multithreaded (shared) use; this is their implementation of a lock-free counter.(Also, this is only half the story: while this extension may provide the needed ordering and visibility guarantees, it does not guarantee atomicity. On Win32 this is guaranteed implicitly by the platforms it runs on: aligned word-sized integer reads and writes are atomic per the platform.)
To nip it in the bud before it starts: without this extension
volatileis not useful for multithreaded programming. Don’t even try. This extension is deprecated, so you should really avoid it if you can.