C++ 11 threads with clang
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.
Related videos on Youtube
bash0r
Updated on June 04, 2022Comments
-
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 over 11 yearsZaffy 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();
-
ZaffyConsider linking with
-pthread
instead of-lpthread
-
-
Puppy over 11 yearsThat would not give undefined reference errors, it would give compiler errors. It is correctly judging the intended language.
-
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 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 over 11 years@bash0r You have to join the thread:
t1.join()
. (And so it is a valid C++ program, you shouldreturn 0
.) -
bash0r over 11 yearsOk thank you guys, you helped me fix my headaches. :x I was struggling with it since 10 hours. :D
-
Philipp Claßen over 11 yearsHaving said that, I also get the exception with
clang 3.2
, even with the extra join. It executes fine when compiled withgcc 4.7.2
. I'm using Arch Linux. -
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 over 11 yearsThis 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 thatclang++
automatically links to the C++ stdlib butclang
doesn't. I can't test it, but probably compiling withclang
and adding-lc++
to the link command would work too. -
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 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 over 11 years@JonathanWakely This behavior i got in 3.2, i have updated my clang yesterday and you're right.
-
Jonathan Wakely over 11 yearsIn fact if I try
clang c.cc -std=c99
then I get the errorerror: 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)