Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference with clang++ with O2

I'm trying CLang 3.4 and libc++ on a project and I get strange linking errors in release mode:

/home/wichtounet/dev/eddic/src/ast/Operator.cpp:17: error: undefined reference to
'std::__1::basic_ostream<char, std::__1::char_traits<char>>&
 std::__1::operator<< <char, std::__1::char_traits<char>, std::__1::allocator<char>>(
   std::__1::basic_ostream<char, std::__1::char_traits<char>>&,
   std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&
 )'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Everything compiles fine. The program links correctly in debug mode, but doesn't when I use O2. In O0, O1 and Os everything works fine, but it doesn't links in O2, O3, Os. I also tried in LTO mode and it works fine.

I tried two versions of libc++ but to no avail.

The code does not seems bad to me:

std::ostream& ast::operator<< (std::ostream& stream, ast::Operator op){
    std::string value = "asd";
    return stream << value;
}

but I haven't a simple example causing the problem.

clang++ is used to both build and links the code. I used "-std=c++1y -stdlib=libc++" to compile and the same plus some library stuff to link.

What could possibly cause that ?

EDIT: Full invocation of link step in release mode:

clang++ -v -use-gold -Iinclude -std=c++1y -stdlib=libc++ -Wextra -Wall -Qunused-arguments -Wuninitialized -Wsometimes-uninitialized -Wno-long-long -Winit-self -Wdocumentation -pedantic -isystem /home/wichtounet/build/modular-boost//include -L /home/wichtounet/build/modular-boost//lib -lboost_program_options -g -DLOGGING_DISABLE -DNDEBUG -O3 -march=native -fvectorize -fslp-vectorize-aggressive -fomit-frame-pointer -o release/bin/eddic "TONS OF DOT O"
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
Selected GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2
 "/usr/bin/x86_64-pc-linux-gnu-ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o release/bin/eddic /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/crtbegin.o -L/home/wichtounet/build/modular-boost//lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../.. -L/lib -L/usr/lib -lboost_program_options "TONS OF DOT O" -lc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/../../../../lib64/crtn.o
src/ast/Operator.cpp:15: error: undefined reference to 'std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
like image 660
Baptiste Wicht Avatar asked Apr 09 '14 19:04

Baptiste Wicht


2 Answers

I was having this problem with code that has long compiled with g++, attempting to compile with clang++. Same symptoms: undefined references to std::__1::basic_ostream<...> that magically went away when -O2 was removed from the compiler options. All similar reports I was finding were about erroneously using clang instead of clang++ to compile C++ code, but that wasn't the case for me: I was using clang++.

I was finally able to determine that the issue (for me) was using #include <iosfwd> (which has iostream forward declarations only, to reduce compile times) in my header (.h) file declaring a class but not using #include <iostream> in the corresponding source (.cpp) file implementing the class.

Once I added the #include <iostream> to the source file and recompiled, these undefined reference errors went away.

like image 69
Michael Kirkham Avatar answered Nov 08 '22 21:11

Michael Kirkham


I notice in the error message "std::__1::operator<<". In the cpp code I see "ast::operator<<". This gives the impression that something is going wroing with the namespaces.

Now I don't know if ast is a class or a namespace, but in both cases that looks a bit off.

If ast is a class, then I'm not sure if the operator<< is allowed as class member. See: http://www.cs.nctu.edu.tw/cis/chinese/doc/research/c++/C++FAQ-English/input-output.html#faq-15.8. It suggests that the operator<< should be implemented as a friend, not as a member of the class. You could try making it a friend method and see if that resolves the problem.

If ast is a namespace, then I would try to remove "asd::", and add seperate namespace declarations around the definition.

like image 29
Johan Avatar answered Nov 08 '22 19:11

Johan