C++ 11 threads with clang

10,294

You are compiling with clang for C not for C++.

  • For C use clang
  • For C++ use clang++

The reason why clang didnt warn you is because you explicitly defined the standard.

Share:
10,294

Related videos on Youtube

bash0r
Author by

bash0r

Updated on June 04, 2022

Comments

  • bash0r
    bash0r almost 2 years

    I wanted to learn use of C++11 threads to speed up compilation of my language (yes I'm building a compiler :x). The first sample I tried threw several errors with clang (3.3 SVN). It compiled fine under GCC (4.6.3).

    I downloaded clang and libc++ from llvm.org's SVN. clang was compiled with GCC (4.6.3) and libc++ was compiled with clang. Both makefiles were generated with CMake.

    For clang I followed this guide: http://llvm.org/docs/GettingStarted.html#checkout

    For libc++ I followed this guide: http://libcxx.llvm.org/

    The piece of code I want to compile (foobar.cpp):

    #include <iostream>
    #include <thread>
    
    using namespace std;
    
    int main(void) {
        thread t1([](void)->void {
            cout << "foobar" << endl;
        });
    }
    

    It compiles fine with clang --std=c++0x -stdlib=libc++ -lpthread foobar.cpp but I get a lot of linker errors:

    /tmp/foobar-59W5DR.o: In function `main':
    foobar.cpp:(.text+0x21): undefined reference to `std::__1::thread::~thread()'
    /tmp/foobar-59W5DR.o: In function `_ZNSt3__16threadC2IZ4mainE3$_0JEvEEOT_DpOT0_':
    foobar.cpp:(.text+0x5c): undefined reference to `operator new(unsigned long)'
    foobar.cpp:(.text+0x186): undefined reference to `operator delete(void*)'
    foobar.cpp:(.text+0x19b): undefined reference to `std::__1::__throw_system_error(int, char const*)'
    /tmp/foobar-59W5DR.o: In function `_ZNSt3__114__thread_proxyINS_5tupleIJZ4mainE3$_0EEEEEPvS4_':
    foobar.cpp:(.text+0x200): undefined reference to `std::__1::__thread_local_data()'
    foobar.cpp:(.text+0x211): undefined reference to `operator new(unsigned long)'
    foobar.cpp:(.text+0x23b): undefined reference to `std::__1::__thread_struct::__thread_struct()'
    foobar.cpp:(.text+0x31b): undefined reference to `operator delete(void*)'
    /tmp/foobar-59W5DR.o: In function `_ZNSt3__110unique_ptrINS_5tupleIJZ4mainE3$_0EEENS_14default_deleteIS3_EEED2Ev':
    foobar.cpp:(.text+0x3dd): undefined reference to `operator delete(void*)'
    /tmp/foobar-59W5DR.o: In function `main::$_0::operator()() const':
    foobar.cpp:(.text+0x3fc): undefined reference to `std::__1::cout'
    /tmp/foobar-59W5DR.o: In function `_ZNSt3__110unique_ptrINS_5tupleIJZ4mainE3$_0EEENS_14default_deleteIS3_EEEC2EPS3_':
    foobar.cpp:(.text+0x4e9): undefined reference to `std::terminate()'
    /tmp/foobar-59W5DR.o: In function `std::__1::__thread_specific_ptr<std::__1::__thread_struct>::reset(std::__1::__thread_struct*)':
    foobar.cpp:(.text._ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_[_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_]+0x57): undefined reference to `std::__1::__thread_struct::~__thread_struct()'
    foobar.cpp:(.text._ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_[_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_]+0x60): undefined reference to `operator delete(void*)'
    /tmp/foobar-59W5DR.o: In function `std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*)':
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x28): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x1ec): undefined reference to `std::__1::ios_base::getloc() const'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x1fe): undefined reference to `std::__1::ctype<char>::id'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x206): undefined reference to `std::__1::locale::use_facet(std::__1::locale::id&) const'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x272): undefined reference to `std::__1::locale::~locale()'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x294): undefined reference to `std::__1::locale::~locale()'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x378): undefined reference to `std::__1::ios_base::clear(unsigned int)'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x3d0): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x3dc): undefined reference to `__cxa_begin_catch'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x3f9): undefined reference to `std::__1::ios_base::__set_badbit_and_consider_rethrow()'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x403): undefined reference to `__cxa_end_catch'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x424): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x43d): undefined reference to `__cxa_end_catch'
    foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x466): undefined reference to `std::terminate()'
    /tmp/foobar-59W5DR.o: In function `std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)':
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0x38): undefined reference to `std::__1::ios_base::getloc() const'
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0x49): undefined reference to `std::__1::ctype<char>::id'
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0x55): undefined reference to `std::__1::locale::use_facet(std::__1::locale::id&) const'
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xac): undefined reference to `std::__1::locale::~locale()'
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xbe): undefined reference to `std::__1::locale::~locale()'
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xcd): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char)'
    foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xdd): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()'
    /tmp/foobar-59W5DR.o: In function `std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)':
    foobar.cpp:(.text._ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_[_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_]+0x215): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)'
    foobar.cpp:(.text._ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_[_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_]+0x389): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()'
    foobar.cpp:(.text._ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_[_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_]+0x3a4): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()'
    /tmp/foobar-59W5DR.o:(.eh_frame+0x47): undefined reference to `__gxx_personality_v0'
    clang-3: error: linker command failed with exit code 1 (use -v to see invocation)
    

    Here are the standard search directories under the two standard libraries. As result of 'clang -Wp,-v -x c++ - -fsyntax-only' I got this:

    I tried clang --std=c++11 -stdlib=libc++ -llibc++ -lpthread -o foobar foobar.cpp but the linker failed again, it does not find libc++. Do I fail on linking to libc++ or is it something more difficult?

    • Philipp Claßen
      Philipp Claßen over 11 years
      Zaffy posted the answer that should fix your problem. But when you run the program, you will get a core-dump. You have to join the thread, otherwise it will crash. Please add: t1.join();
    • Zaffy
      Zaffy
      Consider linking with -pthread instead of -lpthread
  • Puppy
    Puppy over 11 years
    That would not give undefined reference errors, it would give compiler errors. It is correctly judging the intended language.
  • bash0r
    bash0r over 11 years
    @Zaffy First time I ever used 'clang' instead of 'clang++'... What kind of ret*rd am I? Now I get 'terminate called without an active exception \n aborted' when I run the output. Any idea?
  • Zaffy
    Zaffy over 11 years
    @DeadMG If you would use for example standard c++0x and use it with a .c file it won't work. The reason why clang didnt give compiler errors is because he forced standard to be c++0x and used against cpp file so it compiled fine, but didnt link the standard library.
  • Philipp Claßen
    Philipp Claßen over 11 years
    @bash0r You have to join the thread: t1.join(). (And so it is a valid C++ program, you should return 0.)
  • bash0r
    bash0r over 11 years
    Ok thank you guys, you helped me fix my headaches. :x I was struggling with it since 10 hours. :D
  • Philipp Claßen
    Philipp Claßen over 11 years
    Having said that, I also get the exception with clang 3.2, even with the extra join. It executes fine when compiled with gcc 4.7.2. I'm using Arch Linux.
  • Lily Ballard
    Lily Ballard over 11 years
    @PhilippClaßen: What exception? I just tried this (with the t1.join()) in clang 3.1 and it worked for me (OS X).
  • Jonathan Wakely
    Jonathan Wakely over 11 years
    This answer is almost correct. clang inferred the language from the file extension, so it did compile as C++ (nothing to do with -std=c++11). The reason for the linker errors is that clang++ automatically links to the C++ stdlib but clang doesn't. I can't test it, but probably compiling with clang and adding -lc++ to the link command would work too.
  • Zaffy
    Zaffy over 11 years
    @JonathanWakely No. if you pass clang (not clang++) to compile c++ file without explicit -std it will spam errors.
  • Jonathan Wakely
    Jonathan Wakely over 11 years
    @Zaffy, have you actually tried it? clang version 3.3 (trunk 168793) happily compiles a C++ file for me, with no -std, as long as the file extension indicates a C++ file. This is consistent with GCC's behaviour
  • Zaffy
    Zaffy over 11 years
    @JonathanWakely This behavior i got in 3.2, i have updated my clang yesterday and you're right.
  • Jonathan Wakely
    Jonathan Wakely over 11 years
    In fact if I try clang c.cc -std=c99 then I get the error error: invalid argument '-std=c99' not allowed with 'C++/ObjC++' so the -std option doesn't even override the file extension. File extension wins. See also gcc.gnu.org/onlinedocs/gcc/Overall-Options.html (clang's documentation doesn't seem to cover it, but I assume they're going for GCC compatibility in this regard)