请不要回答问题"如何解决此错误消息?"
在gold提供的错误消息中:
/usr/bin/ld.gold: the vtable symbol may be undefined
because the class is missing its key function
什么是key function
?我在dllimport
部分的GCC manual page for Function Attributes下找到了对它的引用。相关文字如下:
在SH Symbian OS目标上,dllimport属性还有另一种影响(原文如此) - 它可以导致类的vtable和运行时类型信息被导出。当类具有dllimport的构造函数或非内联的非纯虚函数时会发生这种情况,并且对于这两个条件中的任何一个,该类还具有内联构造函数或析构函数,并且具有定义的键函数在当前的翻译单位。
从中我可以看出,在某些条件下,在Symbian OS上使用dllimport
属性时,有一些与构造函数或析构函数不同的函数。有意思,但我在Linux上编译Linux,grep -r dllimport
没有透露任何内容。所以本段不适用。
(FWIW问题是从未定义的析构函数派生出来的(在本例中),但是文档和链接器的输出都非常痛苦地区分了一个"关键函数"来自析构函数。对于其他类型的缺失符号,链接器会拼写缺失符号的名称。)
那么,什么是key function
真的?
答案 0 :(得分:25)
键函数定义为类中声明的第一个非内联虚函数。 关于它的官方gcc wiki是this。
答案 1 :(得分:13)
(从评论中移动/扩展)
正如@navylover所解释的那样,关键功能是在类中定义的第一个非内联虚函数;这很重要,因为它被编译器用作传统标记来决定必须发出什么样的TU(因为它必须只发射一次) - 无论哪个TU包含键函数的定义,相应的对象模块都将包含也是如此。
接下来,如果没有TU定义关键功能(例如因为你忘了定义它),vtable将永远不会被发出,因此错误。
黄金试图暗示你正确的方向:如果缺少vtable,可能是因为关键功能也缺失了(再次,因为你没有定义或忘记链接其模块),尽管它可能没有明确地列为未定义的引用(这可能会使你走上正确的轨道),因为在其余的代码中没有人直接调用它 1 ,如下例所示:
struct Test {
virtual void foo();
virtual int bar() {
return 0;
}
};
int main() {
Test t;
t.bar();
return 0;
}
[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
将此与常规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
好的,那又怎样?这不像我必须明确定义vtable,所以我不应该在哪里开始寻找修复这种错误。