Question

Im trying to compile project using boost, binding asio::io_service to boost::thread, and Im getting errors that I dont know how to resolve Using: IBM XL C/C++ for AIX, V11.1 (5724-X13), Version: 11.01.0000.0006 (AIX 7.1)

    "/home/clag/projects/tomas/include/boost/asio/detail/posix_fd_set_adapter.hpp", line 33.30: 1540-0198 (W) The omitted keyword "private" is assumed for base class "noncopyable".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.46: 1540-0219 (S) The call to "boost::bind" has no best match.
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1229 (I) Argument number 1 is an rvalue of type "overloaded function: boost::asio::io_service::run".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1229 (I) Argument number 2 is an rvalue of type "const boost::reference_wrapper<const boost::asio::io_service>".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 30.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)() const, reference_wrapper<const boost::asio::io_service>)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)() const" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1231 (I) The conversion from argument number 2 to "boost::reference_wrapper<const boost::asio::io_service>" uses "the identity conversion".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 20.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)(), reference_wrapper<const boost::asio::io_service>)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)()" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1231 (I) The conversion from argument number 2 to "boost::reference_wrapper<const boost::asio::io_service>" uses "the identity conversion".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.35: 1540-0219 (S) The call to "boost::bind" has no best match.
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1229 (I) Argument number 1 is an rvalue of type "overloaded function: boost::asio::io_service::run".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1229 (I) Argument number 2 is an rvalue of type "boost::asio::io_service *".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 30.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)() const, io_service *)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)() const" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1231 (I) The conversion from argument number 2 to "boost::asio::io_service *" uses "the identity conversion".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 20.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)(), io_service *)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)()" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1231 (I) The conversion from argument number 2 to "boost::asio::io_service *" uses "the identity conversion".
    "/home/clag/projects/tomas/include/boost/asio/impl/write.hpp", line 276.7: 1540-0198 (W) The omitted keyword "private" is assumed for base class "detail::base_from_completion_cond<CompletionCondition>".
    "/home/clag/projects/tomas/include/boost/asio/impl/write.hpp", line 276.7: 1540-0198 (W) The omitted keyword "private" is assumed for base class "detail::base_from_completion_cond>boost::asio::detail::transfer_all_t>"

Code that is causing errors:

    acceptor_thread_.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, boost::cref(*accept_io_service_))));
    for (int i = 0; i < agent_config_.threads(); i++) {
        thread_group_.create_thread(boost::bind(&boost::asio::io_service::run, work_io_service_.get()));
    }

Definitions:

    boost::shared_ptr<boost::asio::io_service> accept_io_service_;
    boost::shared_ptr<boost::thread> acceptor_thread_;
    boost::shared_ptr<boost::asio::io_service> work_io_service_;
    boost::thread_group thread_group_;

Just to mention, this will probably will be just some flag option, but I cant find it anywhere Because same code compiles perfectly fine on Linux(GCC), HP-UX(aCC) and Windows(MSVC).

Thx for help

Was it helpful?

Solution

A quick google search suggest that AIX has had issues with overload resolution, especially when templates are involved. As such, it may be worth trying different approaches to reduce the amount of overload resolutions that need to occur.

For example, boost::mem_fn() could be used in place of boost::bind().

std::size_t (io_service::*run)() = &io_service::run;
boost::thread t(boost::mem_fn(run), io_service);

Furthermore, if the compiler is still having issues resolving the overloads, then consider writing a simple functor. The only requirement for the boost::thread() constructor is that the func argument is copyable and func() must be a valid expression.

struct service_runner
{
  explicit service_runner(boost::shared_ptr<boost::asio::io_service> io_service)
    : io_service(io_service)
  {}
  std::size_t operator()() { return io_service->run(); }
  boost::shared_ptr<boost::asio::io_service> io_service;
};

...

boost::thread t((service_runner(io_service)));

Other points to take into consideration:

  • Prefer compiling conforming code, rather than using compiler flags to allow nonconforming code to compile. In this particular case, io_service::run() is a non-const member function, but the accept_io_service instance argument being bound to it is passed as a constant reference through boost::cref(). Compiler flags, such as gcc's -fpermissive, need to be added to allow for the nonconforming code to compile. Be very careful in using these options, as they may mask serious problems.
  • Consider passing boost::shared_ptr as the instance handle to the binding calls. This will keep the io_service alive as long as the thread is still running. Otherwise, the io_service could be deleted while a thread is still processing its event loop, resulting in a high chance of invoking undefined behavior.

OTHER TIPS

Just curious, are you using the IBM boost library patch for the compiler you are using? http://www-01.ibm.com/support/docview.wss?uid=swg27006911

Looking at the messages for the 4 possible candidates attempted, the differences seem to be const related

No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)() const, reference_wrapper<const boost::asio::io_service
>)".
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)(), reference_wrapper<const boost::asio::io_service>)".
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)() const, io_service *)".
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)(), io_service *)".

Since you are using the V11.1 compiler, there are a couple of fixes not enabled by default that you could try using the following options

-qxflag=EnableIssue214PartialOrdering This will enable several fixes related to C++ core language issue 214

-qxflag=FunctionCVTmplArgDeduction2011 This enables some C++2011 clarifications to argument deduction

These changes are the default on the V12.1 compiler, but not on the V11.1 compiler

I'm adding additinal response, if someone stumbles upon this problem in general. Because I have found out that this is related to compiler not being able to resolve which function to use, if functions have the same name, but different parameters.

Example:

void test(int a);
void test(int a, int b);

Will not work, and will cause similar error as above.
But changing the name like this:

void test(int a);
void test2(int a, int b);

...will work perfectly fine.

This is definitely less overhead solution than creating wrappers (as I myself was doing till observing this).

Hope that someone will find this useful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top