【问题标题】:C++: what are the causes of " undefined reference to 'typeinfo for [class name]' "other than virtual functionsC ++:除了虚函数之外,“未定义对'typeinfo for [class name]'的引用”的原因是什么
【发布时间】:2012-08-07 22:10:55
【问题描述】:

其中一些错误是通过修改解决的

    virtual void draw();

    virtual void draw() {};

但是,除了虚函数之外,这些错误的其他原因是什么? 以下错误可能是什么原因..

  /tmp/cciGEgp5.o:(.rodata._ZTI14CustomXmppPump[typeinfo for CustomXmppPump]+0x18): 
  undefined reference to `typeinfo for XmppPump'

【问题讨论】:

  • 也许你在构建中只有 .h 或 .hpp 文件,没有对应的 .cpp 文件
  • 你混淆了声明和定义。
  • 看起来你正在编译没有 RTTI。请注意,未定义的引用是针对 typeinfo 而不是实际的虚函数。这也是您在 libjingle 网站上找到的 "known issue"
  • 确实使用 -frtti 标志编译。这是编译代码。g++ -g -Wall -DPOSIX -frtti -DEXPAT_RELATIVE_PATH -DFEATURE_ENABLE_SSL -DHAVE_OPENSSL_SSL_H=1 -I ../ -frtti pcp_main.cc ../talk/build/dbg/lib/libxmpphelp.a ../talk/build/dbg/lib/libjingle.a ../talk/build/dbg/lib/libexpat.a ../talk/build/dbg /lib/libsrtp.a -lpthread -lssl .. 仍然得到相同的错误:(...有什么想法吗?
  • @Damon 太好了,你猜它是 libjingle ......:D.. 如果你能纠正我的编译代码会很有帮助......这个错误让我发疯......跨度>

标签: c++


【解决方案1】:

如果您使用 RTTI (-frtti) 进行编译,请确保您的依赖库也使用它编译,而不是 -fno-rtti。否则,当您对使用 -fno-rtti 编译的类进行子类化或使用 dynamic_cast 时,您将收到 typeinfo 错误。

【讨论】:

    【解决方案2】:

    在 GCC 中,第一个非内联虚方法用于确定创建 vtable 和 typeinfo 对象的翻译单元。如果您随后不定义该方法,它会创建您看到的错误,因为它希望您在某处定义该方法,并等待该定义发出该类的 vtable 和 typeinfo 的输出。

    http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html

    当您将 virtual void draw(); 的声明更改为 virtual void draw() {}; 的内联定义时,它会选择一个不同的函数来发出 vtable。

    【讨论】:

    • 除非虚拟的所有定义都是可见的。在这种情况下,每个包含它的 TU 都可以获得自己的副本(不好)。
    • @贾斯汀:正确。它会在目标代码中造成额外的膨胀,必须由链接器消除,这可能很耗时。