Son Do Lenh
Son Do Lenh

Reputation: 896

Compilation error when including boost/thread.cpp

I have the following code using Boost ASIO to setup a TCP client. Here is my code adapted from the Boost doc's chat example.

class AsioCommunicationService {
AsioCommunicationService::AsioCommunicationService(
        boost::asio::io_service& io_service,
        tcp::resolver::iterator endpoint_iterator)
    : io_service_(io_service),
      socket_(io_service)
{
    tcp::endpoint endpoint = *endpoint_iterator;
    socket_.async_connect(endpoint,
    boost::bind(&AsioCommunicationService::handle_connect, this,
    boost::asio::placeholders::error, ++endpoint_iterator));
}

void AsioCommunicationService::handle_connect(const boost::system::error_code& error,
        tcp::resolver::iterator endpoint_iterator)
{
    if (!error)
    {
      boost::asio::async_read(socket_,
          boost::asio::buffer(read_msg_.data(), LampMessage::header_length),
          boost::bind(&AsioCommunicationService::handle_read_header, this,
          boost::asio::placeholders::error));
    }
}
}


class Connection
{
    //init io_service, query, resolve, iterator here
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(host, service);
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator =
  resolver.resolve(query);


    m_session = std::shared_ptr<AsioCommunicationService>(
            new AsioCommunicationService(io_service, iterator));

    //start new thread for io_service.run --> GOT AN ERROR when include boost/thread.hpp
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));

    //this synchronous command would work, but it's blocking the program. I don't want that.
    //io_service.run();
}

Of course, I needed to include boost/thread to make the declaration to variable t in class Connection works. But when I did so, I got this error

#include <boost/thread.hpp>
//ERROR: In function ‘boost::thread&& boost::move(boost::thread&&)’:
///usr/include/boost/thread/detail/thread.hpp:349:16: error: invalid initialization of reference of type ‘boost::thread&&’ from expression of type ‘boost::thread’
//In file included from /usr/include/boost/thread/detail/thread_heap_alloc.hpp:17:0,
//             from /usr/include/boost/thread/detail/thread.hpp:13,
//             from /usr/include/boost/thread/thread.hpp:22,
//             from /usr/include/boost/thread.hpp:13,
//             from /home/son/dev/logistics/src/frameworks/networkService/NetworkConnection.cpp:13:
///usr/include/boost/thread/pthread/thread_heap_alloc.hpp: In function ‘T* boost::detail::heap_new(A1&&) [with T = boost::detail::thread_data<void (*)()>, A1 = void (*&)()]’:
///usr/include/boost/thread/detail/thread.hpp:130:95:   instantiated from here
///usr/include/boost/thread/pthread/thread_heap_alloc.hpp:24:47: error: cannot bind ‘void (*)()’ lvalue to ‘void (*&&)()’
///usr/include/boost/thread/detail/thread.hpp:43:13: error:   initializing argument 1 of ‘boost::detail::thread_data<F>::thread_data(F&&) [with F = void (*)()]’

It would compile and work if I remove the include to boost/thread.hpp, and replace the declaration to t by a simple call to io_service.run(); I'm wondering if this compilation error has to do with boost version. I'm using Boost ASIO 1.42, Ubuntu 11.04 and Eclipse if those are of any help. Thank you in advance.

Upvotes: 1

Views: 3779

Answers (3)

Son Do Lenh
Son Do Lenh

Reputation: 896

After much exploration, following @MvG suggestion, I successfully compiled and linked my simple program by doing the following:

  • manually build and install boost 1.50 (using MvG suggestion)
  • compile and link the source using the following 2 make files (1 for static and 1 for dynamic linking).

Dynamic:

default: test

test.o: test.cpp
    g++-4.5 -std=c++0x -I /home/son/boost_1_50/include/ -c test.cpp 

test: test.o        
    g++-4.5 -std=c++0x -L /home/son/boost_1_50/lib/ test.o -lboost_thread -lboost_system -lboost_chrono -pthread -o test

run: test
    LD_LIBRARY_PATH=/home/son/boost_1_50/lib/ ./test

Static:

default: test

test.o: test.cpp
    g++-4.5 -std=c++0x -I /home/son/boost_1_50/include/ -c test.cpp 

test: test.o
    g++-4.5 -std=c++0x -L /home/son/boost_1_50/lib/ test.o -static -lboost_thread -lboost_system -lboost_chrono -pthread -o test

run: test
    ./test

The test.cpp file is as follows.

#include <boost/thread.hpp>
#include <stdio.h>

int main()
{
    printf("boost thread tested by son\n");
    boost::thread t;
    return 0;
}

That's it. I'm having difficulties compiling this with CMake but that's another problem.

Upvotes: 0

MvG
MvG

Reputation: 60858

I wrote a single file containing a single include directive:

#include <boost/thread.hpp>
  • g++-4.5.4 -std=c++0x -I /usr/include/boost-1_42 -c gave the errors you mention.
  • g++-4.6.3 -std=c++0x -I /usr/include/boost-1_42 -c the same
  • g++-4.7.1 -std=c++0x -I /usr/include/boost-1_42 -c gave even more errors
  • g++-4.7.1 -std=c++0x -I /usr/include/boost-1_49 -c has not a single error
  • g++-4.6.3 and g++-4.5.4 also work without error using boost 1.49

So I'd really suggest you use a more recent version of boost for this. You don't have to install it system-wide, but instead can install it for a single user. So you are not dependent on ubuntu packages.

To manually install boost, I suggest you follow the Getting Started on Unix Variants guide:

  1. Untar boost_1_50_0.tar.bz2 to some temporary source directory and cd into that
  2. Build and install using ./bootstrap.sh --prefix=${HOME}/boost_1_50 && ./b2 install
  3. Compile your application using -I ${HOME}/boost_1_50 to get correct headers
  4. Include ${HOME}/boost_1_50/lib/libboost_thread.a as an argument when linking your application

Using the static libboost_thread.a as opposed to the dynamic libbtoost_thread.so will ensure that you don't have to worry about locating libraries to launch your application. Everything from boost which you need will be included in your main binary.

Upvotes: 3

Son Do Lenh
Son Do Lenh

Reputation: 896

Following the line of reasoning of @MvG of C++11 standard, I did some research. It seems that it's a problem of coordination between gcc and boost provided with Ubuntu Natty, which used -std=c++0x and libboost1.42, respectively.

There's no solution for it, but I used this workaround: commenting out # define BOOST_HAS_RVALUE_REFS in /usr/include/boost/config/compiler/gcc.hpp as follows.

#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
// passed on the command line, which in turn defines
// __GXX_EXPERIMENTAL_CXX0X__.
# define BOOST_HAS_DECLTYPE
//# define BOOST_HAS_RVALUE_REFS
# define BOOST_HAS_STATIC_ASSERT
# define BOOST_HAS_VARIADIC_TMPL
#else

My code compiles like magic now:) Thanks @MvC.

Upvotes: 1

Related Questions