请不要回答"如何解决此错误消息?"的问题.
在gold提供的错误消息中:
/usr/bin/ld.gold: the vtable symbol may be undefined
because the class is missing its key function
Run Code Online (Sandbox Code Playgroud)
什么是key function
?我在该部分下的功能属性的GCC手册页中找到了对它的引用dllimport
.相关文字如下:
在SH Symbian OS目标上,dllimport属性还有另一种影响(原文如此) - 它可以导致类的vtable和运行时类型信息被导出.当类具有dllimport'ed构造函数或非内联非纯虚函数时会发生这种情况,并且对于这两个条件中的任何一个,该类还具有内联构造函数或析构函数,并且具有在现翻译单位.
从中我可以看出,在某些条件下dllimport
,在Symbian OS上使用属性时,有一些与构造函数或析构函数不同的函数.有意思,但我正在为Linux上的Linux编译,并且grep -r dllimport
什么也没透露.所以这一段不适用.
(FWIW问题来自(在这种情况下)来自未定义的析构函数,但是文档和链接器的输出都非常痛苦地区分"关键函数"和析构函数.对于其他类型的缺失符号,链接器拼写缺少符号的名称.)
那么,key function
真的是什么?
Mat*_*lia 17
(从评论中移动/扩展)
正如@navylover所解释的那样,关键函数是类中定义的第一个非内联虚函数; 这很重要,因为它被编译器用作传统标记来决定必须发出什么样的TU(因为它必须只发射一次) - 无论哪个TU包含关键函数的定义,相应的对象模块都将包含vtable也是如此.
因此,如果没有TU定义键函数(例如,因为你忘了定义它),vtable将永远不会被发出,因此错误.
黄金试图暗示你正确的方向:如果vtable丢失,可能是因为关键功能也缺失(再次,因为你没有定义或忘记链接其模块),虽然它可能不会显式列为未定义的引用(可能会使您走上正确的轨道),因为在其余代码中没有人直接调用它1,如下例所示:
struct Test {
virtual void foo();
virtual int bar() {
return 0;
}
};
int main() {
Test t;
t.bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
[matteo@teolapkubuntu /tmp]$ g++ -fuse-ld=gold keyf.cpp
/tmp/ccduMsT3.o:keyf.cpp:function main: error: undefined reference to 'vtable for Test'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
Run Code Online (Sandbox Code Playgroud)
将其与常规GNU ld进行比较,后者只是说
[matteo@teolapkubuntu /tmp]$ g++ keyf.cpp
/tmp/ccUr3Xyi.o: In function `main':
keyf.cpp:(.text+0x1a): undefined reference to `vtable for Test'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
好的,那又怎样?这不像我必须明确定义vtables,所以我应该从哪里开始寻找修复这种错误的绝对不明显.
归档时间: |
|
查看次数: |
6730 次 |
最近记录: |