我只是遇到了以下错误:
(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的
为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?
我只是遇到了以下错误:
(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的
为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?
当前回答
与上面的RTTI、NO-RTTI讨论类似,如果使用dynamic_cast而未能包含包含类实现的目标代码,也会发生此问题。
我在Cygwin上构建代码时遇到了这个问题,然后将代码移植到Linux上。make文件、目录结构甚至gcc版本(4.8.2)在这两种情况下都是相同的,但是代码在Cygwin上可以正确链接和操作,但在Linux上却无法链接。Red Hat Cygwin显然已经对编译器/链接器进行了修改,以避免目标代码链接需求。
Linux链接器错误消息正确地将我引导到dynamic_cast行,但本论坛早期的消息让我寻找缺少的函数实现,而不是实际的问题:缺少目标代码。我的解决方法是在基类和派生类中替换一个虚拟类型函数,例如virtual int isSpecialType(),而不是使用dynamic_cast。这种技术避免了仅仅为了使dynamic_cast正常工作而链接对象实现代码的需求。
其他回答
在基类(抽象基类)中声明虚析构函数,因为不能将析构函数声明为纯虚函数,所以要么必须在抽象类中定义它,就像virtual ~base(){}这样的虚拟定义,要么在任何派生类中定义。
如果你没有做到这一点,你将在链接时以一个“未定义的符号”结束。 因为VMT在根据派生类中的实现更新表时,为所有纯虚函数提供了一个带有匹配NULL的条目。但对于非纯虚函数,则需要在链接时定义,以便更新VMT表。
使用c++filt来要求符号。比如$c++filt _ZTIN10storageapi8BaseHostE 将输出类似"typeinfo for storageapi::BaseHost"的内容。
I encounter an situation that is rare, but this may help other friends in similar situation. I have to work on an older system with gcc 4.4.7. I have to compile code with c++11 or above support, so I build the latest version of gcc 5.3.0. When building my code and linking to the dependencies if the dependency is build with older compiler, then I got 'undefined reference to' error even though I clearly defined the linking path with -L/path/to/lib -llibname. Some packages such as boost and projects build with cmake usually has a tendency to use the older compiler, and they usually cause such problems. You have to go a long way to make sure they use the newer compiler.
检查你的依赖是在没有-f-nortti的情况下编译的。
对于某些项目,你必须显式地设置它,比如在RocksDB中:
USE_RTTI=1 make shared_lib -j4
我有同样的错误时,我的接口(与所有纯虚函数)需要一个更多的函数,我忘记“空”它。
我有
class ICommProvider { public: /** * @brief If connection is established, it sends the message into the server. * @param[in] msg - message to be send * @return 0 if success, error otherwise */ virtual int vaSend(const std::string &msg) = 0; /** * @brief If connection is established, it is waiting will server response back. * @param[out] msg is the message received from server * @return 0 if success, error otherwise */ virtual int vaReceive(std::string &msg) = 0; virtual int vaSendRaw(const char *buff, int bufflen) = 0; virtual int vaReceiveRaw(char *buff, int bufflen) = 0; /** * @bief Closes current connection (if needed) after serving * @return 0 if success, error otherwise */ virtual int vaClose(); };
Last vaClose不是虚拟的,所以编译时不知道从哪里获得它的实现,因此感到困惑。我传达的信息是:
…TCPClient.o:(.rodata+0x38): undefined reference to ' typeinfo for ICommProvider'
简单的更改
virtual int vaClose();
to
virtual int vaClose() = 0;
修复了问题。希望能有所帮助
在我的例子中,它是一个接口类中的虚函数,没有定义为纯虚函数。
class IInterface
{
public:
virtual void Foo() = 0;
}
我忘记了= 0位。