#8092 closed Bugs (wontfix)
stdlibc++ shipped by Apple does not provide std::move
Reported by: | anonymous | Owned by: | John Maddock |
---|---|---|---|
Milestone: | To Be Determined | Component: | config |
Version: | Boost 1.53.0 | Severity: | Showstopper |
Keywords: | xcode, osx, clang | Cc: | mimomorin@… |
Description
After upgrade from Boost 1.52 I get the following error:
In file included from /usr/local/include/boost/variant.hpp:17: In file included from /usr/local/include/boost/variant/variant.hpp:31: In file included from /usr/local/include/boost/variant/detail/initializer.hpp:23: /usr/local/include/boost/variant/detail/move.hpp:100:12: error: no member named 'move' in namespace 'std' using std::move; ~~~~~^
This happens because clang -std=c++0x defines __has_feature(cxx_rvalue_references), but libstdc++ doesn't provide std::move.
Change History (16)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
marshall,
Thank you, I've read about this on stackoverflow. I see two problems here: Firstly, switching to libc++ means that end-user will have to compile boost with libc++ interfaces instead of using binary packages. And secondly, not any C++11 code will compile against libc++ as is.
I believe the problem can be solved with a few directives in config/stdlib/libstdcpp3.hpp
like
// C++11 features in libstdc++ shipped with Apple Clang #if __APPLE__ && (__GNUC_LIBSTD__ <= 4) && (__GNUC_LIBSTD_MINOR__ <= 2) # define BOOST_NO_CXX11_RVALUE_REFERENCES #endif
comment:3 by , 10 years ago
Component: | variant → config |
---|---|
Owner: | changed from | to
Severity: | Regression → Showstopper |
Summary: | Apple clang does not provide std::move → stdlibc++ shipped by Apple does not provide std::move |
So it seems like it is not a regression in Boost.Variant, but a small problem with Boost.Config.
comment:4 by , 10 years ago
Cc: | added |
---|
I'd rather not disable rvalue ref support as it disables a lot of functionality in other libraries which use rvalue refs but not std::move/forward.
There are a number of solutions, none of which are really very nice:
- Declare this combination of compiler/stdlib as unsupported - either the user has to manually define BOOST_NO_CXX11_RVALUE_REFERENCES when they hit this (probably breaks other stuff) or switch to a supported configuration.
- Add yet another config macro for std::move/forward. Unfortunately this is not as easy as it looks as there is no easy correspondence between libstdc++ versions and features (normally the GCC version gives us that, but using clang messes that up as well).
- Add our own std::move/forward as a workaround - but this shares the configuration hell we have in the above case as well.
- Suggest library authors use boost::move - but may be a heavyweight solution?
- Suggest library authors use simple type casts (to rvalue reference) rather than std::move - but this uglifies code.
So... my inclination is to say "won't fix", but I'd welcome other ideas.
Also adding Michel Morin into this as he's edited clang.hpp quite a bit.
comment:5 by , 10 years ago
There's a clang-darwin config that we ship. (tools/build/v2/tools/clang-darwin.jam) Shouldn't these changes (whatever they turn out to be) go in there instead? (since the situation is particular to Mac OS X)
Note that there is at least one bug vs. the clang-darwin toolset. (#5957) [ Yeah, someone added a comment to a closed ticket. Really should be it's own ticket - but read the last comment ]
follow-up: 7 comment:6 by , 10 years ago
Detecting the clang and libstdc++-4.2 configuration is not so difficult.
(I needed to detect it in boost/type_traits/intrinsics.hpp
to avoid
the problems about __is_pod
/__is_empty
.)
But I don't want to disable rvalue refs, since the compiler does
support the feature.
Another solutions would be to use workaround implementations, but
- We cannot add workaround implementations of
std::move/forward
asboost::move/forward
, since the nameboost::move/forward
is already used by the Boost.Move library. - We cannot use
boost::forward
in Boost.Move as a drop-in replacement ofstd::forward
, sinceboost::forward
is not equivalent tostd::forward
. We cannot usestatic_cast<T&&>
either, due to the same reason.
I don't think it's worth the effort to support this configuration. I would say "Don't turn on -std=c++0x option in this configuration or use another stdlib that supports C++11."
comment:7 by , 10 years ago
We cannot use
static_cast<T&&>
either, due to the same reason.
I meant that std::forward<T>(x)
is not always replaceable with
static_cast<T&&>(x)
. See, for example, N2951.
comment:8 by , 10 years ago
If Clang + libstdc++4.2 is detectable, then adding our own std::forward/std::move seems by far the best solution.
comment:9 by , 10 years ago
So a possible fix would be to add:
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \ && defined(__APPLE__) && defined(_GLIBCXX_VERSION) \ && (_GLIBCXX_VERSION <= 20070719) // move and forward go here #endif
But where do we add this? The obvious place is in config/suffix.hpp but as move/forward depend on remove_reference that's a really bad idea (cyclic dependencies etc). Does clang have an intrinsic for remove_reference? If so we could make it a clang specific fix in clang.hpp I guess...
John.
comment:10 by , 10 years ago
As people propose solutions, I want everyone to keep in mind:
This is not a "clang problem". This is a "clang on Mac OS X when used with the old version of libstdc++ that Apple ships" problem. If you have a modern libstdc++, this is not a problem. If you use libc++, this is not a problem.
Any solution should should be very constrained, so as not to break other systems - hence my suggestion earlier to consider the clang-darwin
toolset.
comment:11 by , 10 years ago
Do we really need to detect the clang and libstdc++-4.2 configuration?
What's the problem of always using Boost versions of move
/forward
template <typename T> inline T&& forward(typename boost::remove_reference<T>::type& t) BOOST_NOEXCEPT { return static_cast<T&&>(t); } template <typename T> inline T&& forward(typename boost::remove_reference<T>::type&& t) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(!boost::is_lvalue_reference<T>::value); return static_cast<T&&>(t); } template <typename T> inline typename boost::remove_reference<T>::type&& move(T&& t) BOOST_NOEXCEPT { return static_cast<typename boost::remove_reference<T>::type&&>(t); }
?
comment:12 by , 10 years ago
What's the problem of always using Boost versions of move/forward
Well it means changing a lot of library's code, in order to support a compiler/stdlib configuration that's basically broken and isn't itself supported by it's vendors.
My gut feeling is to close this as "won't fix", Marshall you're more familiar with this platform than I am, is that reasonable?
comment:13 by , 9 years ago
I believed that we decided to don't support this combination.
+ 1 do "won't fix"
comment:14 by , 9 years ago
I concur with "won't fix".
If you want to use C++11 stuff on Mac OS X, use a C++11 compliant compiler _and_ a C++11 library. (aka clang and libc++).
comment:15 by , 9 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:16 by , 9 years ago
that's due to the weirdo support of 2010 kind of inner faulty bridge, if set your target to cxx98 or fully built against cx11 there is no issue, this bug should be sent at Apple with the dedicated mention "swap your arse guys", numerous issues are logged because of the new itunes e.g xcode 4 which is a mess, buggy and a robbery.
You might want to check out this blog post that I wrote about clang and C++11, which addresses this very topic:
http://marshall.calepin.co/llvmclang-and-standard-libraries-on-mac-os-x.html