标头包含标准 C++ 库后的未定义符号
Posted
技术标签:
【中文标题】标头包含标准 C++ 库后的未定义符号【英文标题】:Undefined symbols after header inclusion of std c++ library 【发布时间】:2014-08-30 16:05:06 【问题描述】:#include <iostream>
int main()
std::cout << 1.0;
return 0;
我使用命令g++ -E main.cpp
在预处理器运行后获取此编译单元。
经过预处理后,它包含大约 20k 行。
它包含了这部分代码,定义为operator<<(double __f)
。
namespace std __attribute__ ((__visibility__ ("default")))
# 55 "/usr/include/c++/4.7/ostream" 3
template<typename _CharT, typename _Traits>
class basic_ostream : virtual public basic_ios<_CharT, _Traits>
public:
typedef _CharT char_type;
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
typedef _Traits traits_type;
typedef basic_streambuf<_CharT, _Traits> __streambuf_type;
typedef basic_ios<_CharT, _Traits> __ios_type;
typedef basic_ostream<_CharT, _Traits> __ostream_type;
typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> >
__num_put_type;
typedef ctype<_CharT> __ctype_type;
# 81 "/usr/include/c++/4.7/ostream" 3
explicit
basic_ostream(__streambuf_type* __sb)
this->init(__sb);
//.........................................................
__ostream_type&
operator<<(double __f)
return _M_insert(__f);
//.........................................................
;
接下来,运行
g++ -c main.cpp
和 nm main.o
000000000000005a t _GLOBAL__sub_I_main
000000000000001d t _Z41__static_initialization_and_destruction_0ii
U _ZNSolsEd
U _ZNSt8ios_base4InitC1Ev
U _ZNSt8ios_base4InitD1Ev
U _ZSt4cout
0000000000000000 r _ZStL19piecewise_construct
0000000000000000 b _ZStL8__ioinit
U __cxa_atexit
U __dso_handle
0000000000000000 T main
_ZNSolsEd
是 operator<<(double)
的错位名称,该行具有 "U" The symbol is undefined
。但是这个运算符的定义是在编译的源代码中。这是什么原因?
【问题讨论】:
在某处有extern template
吗?请注意,nm -C
更具可读性。
@0x499602D2 没有错误消息,除非您以某种方式阻止编译器将-lstdc++
传递给链接器。
【参考方案1】:
这一行:
extern template class basic_ostream<char>;
告诉编译器该函数已经在其他地方可用,它不应该为它发出任何代码(除了可能用于内联),就像 inline
在 C99 中所做的那样。
【讨论】:
以上是关于标头包含标准 C++ 库后的未定义符号的主要内容,如果未能解决你的问题,请参考以下文章