Beast: `std::list<T, beast::handler_alloc<T, H>>` fails to compile on gcc 5.x and below.

Created on 7 Jun 2017  Â·  14Comments  Â·  Source: boostorg/beast

I'm using Beast's master branch.

The std::list implementation that ships with gcc 5.x and below doesn't wrap allocator usage in std::allocator_traits.

Since beast::handler_alloc doesn't provide some optional member typedefs, this leads to compile errors when instantiating std::list<T, beast::handler_alloc<T, H>>:

/usr/include/c++/5/bits/stl_list.h:520:58: error: no type named ‘pointer’ in ‘std::__cxx11::list<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Tp_alloc_type {aka class beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler>}’
       typedef typename _Tp_alloc_type::pointer           pointer;
                                                          ^
/usr/include/c++/5/bits/stl_list.h:521:58: error: no type named ‘const_pointer’ in ‘std::__cxx11::list<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Tp_alloc_type {aka class beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler>}’
       typedef typename _Tp_alloc_type::const_pointer     const_pointer;
                                                          ^
/usr/include/c++/5/bits/stl_list.h:522:58: error: no type named ‘reference’ in ‘std::__cxx11::list<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Tp_alloc_type {aka class beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler>}’
       typedef typename _Tp_alloc_type::reference         reference;
                                                          ^
/usr/include/c++/5/bits/stl_list.h:523:58: error: no type named ‘const_reference’ in ‘std::__cxx11::list<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Tp_alloc_type {aka class beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler>}’
       typedef typename _Tp_alloc_type::const_reference   const_reference;

This is fixed in gcc 6 and above. While this is a bug in libstdc++ ([bug report]), the maintainer says he does not plan to backport the fix into 5.x, and 5.x is still in widespread use.

All 14 comments

Very nice to see someone using the handler allocator! You're writing a composed operation I take it then? Have you seen this tutorial?
http://vinniefalco.github.io/beast/beast/core/op_tutorial.html

Anyway if its as easy as adding those types, I'll make sure its in v50 (doing it now)

Keep opening those issues and keep those bugs and suggestions coming, they are really helping to improve Beast!!!

Thanks @vinniefalco! Sorry I've been quiet -- work has kept me sorely busy.

Indeed I am writing a composed operation! I saw that you added the composed op tutorial, but haven't read it yet. I'll read it and give you feedback today or tomorrow -- though I anticipate that you probably nailed it. ;)

It looks like the libstdc++ in question also wants the destroy() and construct() member functions. :/

/usr/include/c++/5/bits/list.tcc:75:4: error: ‘std::__cxx11::_List_base<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Node_alloc_type {aka class beast::handler_alloc<std::_List_node<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >, main_handler>}’ has no member named ‘destroy’
    _M_get_Node_allocator().destroy(__tmp);
/usr/include/c++/5/bits/stl_list.h:574:8: error: ‘std::__cxx11::_List_base<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Node_alloc_type {aka class /usr/include/c++/5/bits/stl_list.h:574:8: error: ‘std::__cxx11::_List_base<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, beast::handler_alloc<boost::asio::basic_stream_socket<boost::asio::ip::tcp>, main_handler> >::_Node_alloc_type {aka class beast::handler_alloc<std::_List_node<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >, main_handler>}’ has no member named ‘construct’
        _M_get_Node_allocator().construct(__p,

After I un-#ifdefed the destroy and added:

    template <class U, class... Args>
    void construct(U* ptr, Args&&... args) {
        ::new((void*)ptr) U(std::forward<Args>(args)...);
    }

It compiled.

Can I just add them in and everything will be ok?

Those are the only changes needed to make it work for me with gcc 5.4.

I suppose a consequence is that std::allocator_traits will use the construct and destroy functions you write, making Beast responsible for their correctness. A compromise might be to #ifdef the functions in for specific versions of libstdc++. I can come up with an expression to do this, if you're interested. I'm also fine with a wontfix if this is too much of a question mark -- using boost::container::list instead of std::list is an easy workaround. :)

The construct and destroy in my commit look benign, can you think of a scenario where they won't work?

No, I can't -- they look benign to me, too.

This will go into v51 (in the Pull Request queue now)

Thank you Vinnie!

I'm working on conditionally activating this based on the version of libstdc++

Got that working with help from @glenfe, this is the secret sauce:

#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 60000)

One way, using Boost.Predef.

#include <boost/predef.h>
// ...
#if BOOST_LIB_STD_GNU && BOOST_LIB_STD_GNU < BOOST_VERSION_NUMBER(46, 4, 27)
    void destroy(...);
    void construct(...);
#endif

I pulled the 46.4.27 number from Wandbox running gcc 6.1.0.

But it looks like you and @glenfe beat me. ;)

That's good to have in the back pocket just in case though

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nguoithichkhampha picture nguoithichkhampha  Â·  7Comments

fpingas picture fpingas  Â·  7Comments

inetic picture inetic  Â·  4Comments

a1987zz picture a1987zz  Â·  6Comments

maddinat0r picture maddinat0r  Â·  4Comments