2

The following code need pthread link option to compile, and i don't understand why. Do you have any idea?

I'm using gcc 7.2.0

#include <future>

int sum = 0;

void func()
{
   for(int i=0; i < 10; ++i)
      sum +=i;
}

int main()
{
    std::future<void> f =  std::async(std::launch::async, func);
    return 0;
}

Compiling with

g++ -o test test.cpp

provides the following error

/tmp/ccoEkyeZ.o: dans la fonction « std::thread::thread<std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (*)()> >, void>::_Async_state_impl(std::thread::_Invoker<std::tuple<void (*)()> >&&)::{lambda()#1}>(std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (*)()> >, void>::_Async_state_impl(std::thread::_Invoker<std::tuple<void (*)()> >&&)::{lambda()#1}&&) »:
test.cpp:(.text._ZNSt6threadC2IZNSt13__future_base17_Async_state_implINS_8_InvokerISt5tupleIJPFvvEEEEEvEC4EOS8_EUlvE_JEEEOT_DpOT0_[_ZNSt6threadC5IZNSt13__future_base17_Async_state_implINS_8_InvokerISt5tupleIJPFvvEEEEEvEC4EOS8_EUlvE_JEEEOT_DpOT0_]+0x30): référence indéfinie vers « pthread_create »
collect2: error: ld returned 1 exit status

while using

g++ -o test test.cpp -lpthread

has no issue.

is this normal? do i missing something? my code doesn't have pthread_create somewhere

bonpiedlaroute
  • 173
  • 1
  • 9
  • Because your C++ Standard Library implementation uses pthreads. –  Feb 18 '18 at 00:25
  • @NeilButterworth, yes i suspect that, but this flag shoudn't be managed in the standard library implementation? – bonpiedlaroute Feb 18 '18 at 00:33
  • 3
    Ideally, yes, and it is in the MinGW GCC implementations I use - which one are you using? But it doesn't have to be - the C++ Standard says nothing about how compiling and linking should be managed on specific platforms. –  Feb 18 '18 at 00:35
  • i'm using gcc Ubuntu 16.04 – bonpiedlaroute Feb 18 '18 at 00:46
  • It is recommended to use the switch `-pthread` rather than the linker flag `-lpthread`. – Galik Feb 18 '18 at 01:06
  • 1
    fwiw, currently `GCC` also implements the *filesystem* `TS` as a separate library too, requiring `-lstdc++fs` for the linker – Galik Feb 18 '18 at 01:11

1 Answers1

4

Your code may not have a pthread_create in it but just think for a minute what asynchronous processing actually entails.

It's a near certainty that an asynchronous function will be run in a separate thread so that it can, well, run asynchronously with the main code. That should be evident by the fact your error message contains the text std::thread several times.

And, in your environment, it seems that std::thread uses pthreads under the covers.

This is really no different to your code containing cout << someInt and it possibly complaining about a missing itoa-like function for doing integer-to-string conversions. Your setup would probably be seriously broken if it included streams but no standard conversions but the concept is still valid.

The executable must have access to all the stuff you explicitly call, plus all of the other dependencies that entails.


For what it's worth, this is covered (albeit vaguely) in the gcc docs (my emphasis):

When you link a multithreaded application, you will probably need to add a library or flag to g++. This is a very non-standardized area of GCC across ports. Some ports support a special flag (the spelling isn't even standardized yet) to add all required macros to a compilation (if any such flags are required then you must provide the flag for all compilations not just linking) and link-library additions and/or replacements at link time. The documentation is weak.

On several targets (including GNU/Linux, Solaris and various BSDs) -pthread is honored.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • i do agree, and understand that, my question was most on the fact that this flag should be managed by the stl implementation – bonpiedlaroute Feb 18 '18 at 00:37
  • 1
    @bonpiedlaroute Well, `std::thread` doesn't do this either, so it's a moot point if it's not addressed at the root. Use a build system like CMake and it will do it automatically for you using `find_packages(Threads)` and linking to `${CMAKE_THREADS_LIB_INIT}`. Not ideal, but it's reality. – Alex Huszagh Feb 18 '18 at 00:46