带有clang++和O2的未定义引用
Undefined reference with clang++ with O2
我在一个项目上尝试CLang 3.4和libc++,但在发布模式中遇到了奇怪的链接错误:
/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)
一切都很顺利。程序在调试模式下正确链接,但在我使用O2时没有。在O0、O1和Os中,一切都很好,但在O2、O3、Os中却没有联系。我也尝试过LTO模式,它运行良好。
我尝试了两个版本的libc++,但都没有用。
代码在我看来并不坏:
std::ostream& ast::operator<< (std::ostream& stream, ast::Operator op){
std::string value = "asd";
return stream << value;
}
但我没有一个简单的例子造成这个问题。
clang++用于构建和链接代码。我使用了"-std=c++1y-stdlib=libc++"进行编译,并添加了一些库内容进行链接。
可能是什么原因造成的?
编辑:在发布模式下完全调用链接步骤:
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)
我对长期使用g++编译的代码遇到了这个问题,试图使用clang++进行编译。相同症状:未定义引用std::__1::basic_stream<…>当-O2从编译器选项中删除时,它神奇地消失了。我发现的所有类似的报告都是关于错误地使用clang而不是clang++编译C++代码的,但我的情况并非如此:我使用的是clang++。
我终于能够确定(对我来说)问题是在我的头(.h)文件中使用#include <iosfwd>
(它只有iostream前向声明,以减少编译时间)来声明一个类,而在实现该类的相应源(.cpp)文件中不使用#include <iostream>
。
一旦我将#include <iostream>
添加到源文件并重新编译,这些未定义的引用错误就消失了。
我注意到错误消息"std::__1::operator<<"。在cpp代码中,我看到了"ast::operator<<"。这给人的印象是名称空间出现了问题。
现在我不知道ast是一个类还是一个命名空间,但在这两种情况下,这看起来都有点不对劲。
如果ast是一个类,那么我不确定运算符<lt;被允许作为类成员。请参阅:http://www.cs.nctu.edu.tw/cis/chinese/doc/research/c++/C++常见问题英文版/in-out.html#FAQ-15.8。这表明运算符<lt;应该作为朋友实现,而不是作为类的成员实现。你可以试着把它作为一种朋友的方法,看看它是否能解决问题。
如果ast是一个命名空间,那么我会尝试删除"asd::",并在定义周围添加单独的命名空间声明。
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用