Opened 8 years ago
Closed 8 years ago
#10125 closed Bugs (fixed)
call_once: compile errors in variadic version with rvalue reference emulation
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | Boost 1.56.0 | Component: | thread |
Version: | Boost 1.55.0 | Severity: | Problem |
Keywords: | Cc: | raad@… |
Description
In the variadic template version, boost::call_once uses BOOST_THREAD_RV_REF for the function and function argument parameters.
If the Boost.Move rvalue reference emulation is active, this only compiles for classes that use one of the macros in Boost.Move in their class definiton. Notably, it dooes not compile for Boost.Bind and Boost.Function objects.
Could this be changed to use BOOST_THREAD_FWD_REF instead of BOOST_THREAD_RV_REF or could const& overloads be added?
Attachments (2)
Change History (15)
comment:1 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 8 years ago
Please see the attached simple example for MSVC12. The error message is:
boost_call_once_test\boost_call_once_test\boost_call_once_test.cpp(19): error C2665: 'boost::call_once' : none of the 2 overloads could convert all the argument types 1> boost_call_once_test\boost_call_once_test\boost\thread\win32\once.hpp(232): could be 'void boost::call_once(boost::once_flag &,void (__cdecl *)(void))' 1> boost_call_once_test\boost_call_once_test\boost\thread\once.hpp(35): or 'void boost::call_once<boost::once_flag>(Function,boost::once_flag &)' 1> with 1> [ 1> Function=boost::once_flag 1> ] 1> while trying to match the argument list '(boost::once_flag, boost::_bi::bind_t<void,boost::_mfi::mf0<void,test_class>,boost::_bi::list1<boost::_bi::value<T>>>)' 1> with 1> [ 1> T=test_class 1> ]
I don't know why the error message doesn't even mention
void call_once<Function>(once_flag& flag, boost::rv<Function> &f)
, IntelliSense suggests that overload too.
clang gives similar errors.
comment:3 by , 8 years ago
I have reached to make it work with
#define BOOST_THREAD_VERSION 4 //#define BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_THREAD_PROVIDES_ONCE_CXX11
I don't remember why BOOST_THREAD_PROVIDES_ONCE_CXX11 is not defined when BOOST_THREAD_VERSION is defined.
Please could you check if this work for you. I will comeback when I found why I have not defined it.
comment:4 by , 8 years ago
I have found this comment
// For C++11 call_once interface the compiler MUST support constexpr. // Otherwise once_flag would be initialized during dynamic initialization stage, which is not thread-safe. #if defined(BOOST_THREAD_PROVIDES_ONCE_CXX11) #if defined(BOOST_NO_CXX11_CONSTEXPR) #undef BOOST_THREAD_PROVIDES_ONCE_CXX11 #endif #endif
And
#if BOOST_THREAD_VERSION>=3 // ONCE_CXX11 // fixme BOOST_THREAD_PROVIDES_ONCE_CXX11 doesn't works when thread.cpp is compiled BOOST_THREAD_VERSION 3 #if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \ && ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11 #define BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 #endif
I will comeback with more insight.
comment:5 by , 8 years ago
Defining BOOST_THREAD_PROVIDES_ONCE_CXX11 would work for me as I don't actually need this for MSVC, only for the latest clang. I only use MSVC for testing as I don't have access to clang regularly. But unfortunately I still have to define BOOST_NO_CXX11_RVALUE_REFERENCES as the standard library I have to use with clang is not move-aware and does not provide std::move and std::forward :-(
comment:6 by , 8 years ago
Boost doesn't supports this combination. I think that it would be better to remove this checker and don't use C++11 with this library.
comment:7 by , 8 years ago
I see, thank you. I have to change to libc++ as soon as possible. But everything in Boost works except for this single compile error when variadic templates are switched on.
comment:8 by , 8 years ago
I have assumed that if the compiler has variadic templates it has move semantic. In order to support the configuration you want I would need to make the distinction. Do you think it is worth the effort?
comment:9 by , 8 years ago
Well, there is a workaround (also disabling variadic templates when disabling rvalue references), so it's not critical.
But as the rest of Boost (including the rest of Boost.Thread) works in this configuration with variadic templates and without rvalue references and it seems that I'm not the only one using the latest clang with an older standard library, I think it's worth it if it's not too much work.
Maybe the simplest solution would be to disable the variadic version of call_once if BOOST_NO_CXX11_RVALUE_REFERENCES is defined? The attached patch works for me with all compiler and standard library combinations.
by , 8 years ago
Attachment: | call_once_variadic.patch added |
---|
comment:11 by , 8 years ago
Milestone: | To Be Determined → Boost 1.56.0 |
---|
comment:13 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Please, could you show an example an the compile error?