
On Sunday 13 January 2013 16:08:28 Vicente J. Botet Escriba wrote:
C++11 defines the following interface. There is no STD_ONCE_INIT initializer.
struct once_flag {
constexpr once_flag() noexcept; once_flag(const once_flag&) = delete; once_flag& operator=(const once_flag&) = delete;
}; template<class Callable, class ...Args> void call_once(once_flag& flag, Callable func, Args&&... args);
Could this once_flag be implemented using the trick you used to mask the atomic dependency on the header file?
Hmm, I didn't know the standard defined call_once.
It is possible to define once_flag as defined by the standard.
Could you work on complementing your patch to take care of the C++11 interface?
Ok, but I'll have to modify the way BOOST_THREAD_PROVIDES_ONCE_CXX11 is defined to disable the C++11 interface when constexpr is not available.
But the previous implementation seem incorrect to me. once_flag *must* be either POD or have a constexpr default constructor while the previous code (as well as the code in win32/once.hpp) uses BOOST_CONSTEXPR which can be empty. BOOST_THREAD_PROVIDES_ONCE_CXX11 macro doesn't depend on constexpr or noexcept availability so it can't be used to enable C++11 implementation.
Andrey, could you explain me why once_flag must be either be a POD or follow strictly the C++11 interface? In other words, what are the problems defining it as follows?
struct once_flag { once_flag(); private: once_flag(const once_flag&); once_flag& operator=(const once_flag&); };
once_flag must always be statically initialized, that's the key feature that allows call_once to be thread-safe. In C++03 this can only be guaranteed for POD types. C++11 also includes constant initialization into static initialization (i.e. when objects are initialized with constexpr constructors). All other objects are initialized during dynamic initialization, which is not thread-safe.