3

Boost Intrusive's unordered_set is broken if you do a vanilla install of Fedora 17 which comes with GCC 4.7 and Boost 1.48, and use C++11 mode. On Fedora 16, which comes with GCC 4.6.2 and Boost 1.47, it works. This breaks real code, and it even breaks the example in the official documentation:

#include <boost/intrusive/unordered_set.hpp>

using namespace boost::intrusive;

struct MyClass : public unordered_set_base_hook<>
{};

typedef unordered_set<MyClass>::bucket_type   bucket_type;
typedef unordered_set<MyClass>::bucket_traits bucket_traits2;

int main()
{
   bucket_type buckets[100];
   unordered_set<MyClass> uset(bucket_traits2(buckets, 100)); // FAILS
}

The error message:

/usr/include/boost/intrusive/hashtable.hpp:227:65: error: use of deleted function ‘constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive::detail::bucket_traits_impl >::type>&)’

In file included from /usr/include/boost/intrusive/hashtable.hpp:30:0, from /usr/include/boost/intrusive/unordered_set.hpp:18, from t.cpp:23:

/usr/include/boost/intrusive/detail/hashtable_node.hpp:80:8: note: ‘constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive::detail::bucket_traits_impl >::type>&)’ is implicitly declared as deleted because ‘boost::intrusive::detail::bucket_traits_impl >::type>’ declares a move constructor or move assignment operator

Here is the code it refers to, hashtable.hpp:227:

template<class BucketTraits>
bucket_plus_size(BOOST_FWD_REF(BucketTraits) b_traits)
   : bucket_traits_(::boost::forward<BucketTraits>(b_traits))
{}

In Boost 1.47, this was:

bucket_plus_size(const bucket_traits &b_traits)
   : bucket_traits_(b_traits)
{}                 

BOOST_FWD_REF(TYPE) on my system is defined as TYPE && by default, but if BOOST_NO_RVALUE_REFERENCES is defined then it becomes const TYPE &. And if I do define it that way, the code compiles!

Any thoughts on why this is? Is it GCC's fault, Boost's, Fedora's, or mine?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 2
    A good start would be to test with Boost 1.49.0, in case it's an Intrusive (or Config) bug that's already been fixed. – ildjarn May 03 '12 at 23:46
  • I tested it with Boost 1.49 and GCC 4.7.0 (same as in the OP), and it worked, but this is on Mac OS rather than Fedora. – John Zwinck May 05 '12 at 02:55
  • A second problem with intrusive::unordered_set in Boost 1.48 is that BOOST_FOREACH fails on it. I wonder if the Fedora package maintainers should consider defining BOOST_NO_RVALUE_REFERENCES in Boost's config.hpp so others don't have to. – John Zwinck May 05 '12 at 03:01
  • Why would they do that when it already works with Boost 1.49? – ildjarn May 05 '12 at 03:49
  • Because Fedora 17 looks like it's going to "ship with" Boost 1.48 (i.e. that's what you get if you `yum install boost-devel`), and they don't generally update package versions until the next version of Fedora (which is six months away). A targeted bugfix could be done though. – John Zwinck May 05 '12 at 03:54
  • Ah, understood. Personally, I'd just build from source and ditch the package. :-] – ildjarn May 05 '12 at 03:56
  • 1
    That's an "infectious" approach, though: once you do that, you'll be on the path toward building lots of things from source, because other packages that you could get from the yum repos will depend on the Boost that's there, so making Boost from source may force you to build other things from source as well. This is considered fine on some systems, but it's not really normal on Fedora or Ubuntu for example, where the distributors are expected to maintain some semblance of order even when third-party libraries are misbehaving. – John Zwinck May 05 '12 at 04:02

1 Answers1

1

This looks like the same problem described at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53234

i.e. Boost 1.48 assumes the old behaviour of GCC 4.6, but GCC 4.7 was changed to implement the correct C++11 semantics regarding implicitly-defined copy/move constructors.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521