Opened 10 years ago

Closed 9 years ago

Last modified 9 years ago

#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 Marshall Clow, 10 years ago

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

comment:2 by anonymous, 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 anonymous, 10 years ago

Component: variantconfig
Owner: changed from ebf to John Maddock
Severity: RegressionShowstopper
Summary: Apple clang does not provide std::movestdlibc++ 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 John Maddock, 10 years ago

Cc: mimomorin@… 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 Marshall Clow, 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 ]

comment:6 by Michel Morin, 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 as boost::move/forward, since the name boost::move/forward is already used by the Boost.Move library.
  • We cannot use boost::forward in Boost.Move as a drop-in replacement of std::forward, since boost::forward is not equivalent to std::forward. We cannot use static_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."

in reply to:  6 comment:7 by Michel Morin, 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 Sebastian Redl, 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 anonymous, 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 Marshall Clow, 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 Michel Morin, 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 John Maddock, 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 viboes, 9 years ago

I believed that we decided to don't support this combination.

+ 1 do "won't fix"

comment:14 by Marshall Clow, 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 viboes, 9 years ago

Resolution: wontfix
Status: newclosed

comment:16 by koala0xcafe, 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.

Note: See TracTickets for help on using tickets.