“非虚拟 thunk 到<方法名称>”,引用自:中的 Vtable 方法名称>
在调试模式下编译时,我的 xcode 编译出现这些链接错误:
"<method name>", referenced from:
Vtable for <classname>in <objectfile.o>
"non-virtual thunk to <method name>", referenced from:
Vtable for <classname>in <objectfile.o>
奇怪的是:它只发生在我的构建目标之一中(两个目标对于该代码几乎相同),此外,如果这些方法是在头文件中定义的而不是 .cpp 它对于两个目标都可以正常工作。
所有这些方法都是纯虚拟的。发生这些错误的类继承自多个类,但只有其中一个类会导致这些错误。
有人知道导致此错误的原因吗?
When compiling in debug mode my xcode compilation has these linking errors:
"<method name>", referenced from:
Vtable for <classname>in <objectfile.o>
"non-virtual thunk to <method name>", referenced from:
Vtable for <classname>in <objectfile.o>
the strange thing is: It only occurs in one of my build targets (both targets are pretty much the same for that code), plus if these methods are defined in the header file instead of the .cpp it works fine for both targets.
All of those methods are pure virtual. The class where these errors occur inherits from multiple classes but only one of those causes these errors.
Anyone has any idea of what is causing this error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
遇到同样的问题。
当我们定义一个虚拟成员函数(在 .h 头文件中)但没有实现它(在 .cpp 文件中)时,就会发生这种情况。
就我而言,实现位于 #define 内,无法实际编译。对于此类常见错误,GCC 应该有更明确的信息,例如
Got hit by the same issue.
It simply happened when we defined a virtual member function (in the .h header file) but not implemented it (in the .cpp file).
In my case, the implementation was inside a #define that prevented to be actually compiled. GCC should have more explicit message for that kind of common mistake such as
使用 C++/QtCreator 开发时遇到此问题,这是由于 .pro 文件中多次包含同一文件引起的。确保检查每个必要的头文件/源文件仅在
HEADERS += \
和SOURCES += \
下列出一次!Encountered this issue when developing with C++/QtCreator, it was caused by including the same file multiple times in the .pro file. Make sure to check each necessary header/source file is only listed under
HEADERS += \
andSOURCES += \
once!我们将从明显的位开始:这表明 cpp 没有链接,或者调用是直接引用的而不是定义的(您可以定义一个纯虚拟)。
除此之外,构建设置可能存在差异 - 一般来说,这是因为默认符号可见性(Xcode 别名标志和推荐设置):
还有一些其他构建设置可能会干扰 - 不知道你的项目是如何构造的。 ..这个列表可能会变得相当大。
we'll start with the obvious bits: this suggests that the cpp is not linked in, or that the calls are referenced directly and not defined (you can define a pure virtual).
beyond that, there may be differences in build settings - generally, this is because of default symbol visibility (Xcode alias flags, and recommended settings):
there are a few other build settings which could interfere -- idk how your projects are structured so... this list can become rather large.
谷歌引导我来到这里“未定义的非虚拟重击”,
我真的很想向其他人提及这一点(因为我花了将近半天的时间来跟踪这个问题并注释掉代码)。
在我的具体情况下,此错误的原因是未配对的
#pragma pack(push, 4)
,而没有#pragma pack(pop)
围绕 C 结构,并强制执行内存占用(通过协议) spec)在头文件中,这会弄乱接下来包含的所有头文件。我想最好不要编译这样的代码库,然后默默地构建可执行文件,其中单元具有相同类的不同内存占用。
因此,也许原始问题可能存在某种潜在问题,在某种程度上与二进制表示相关,可能具有一些不同的编译标志。因此,当 h 中定义实现时,问题就消失了,因为它实际上在两个不同的编译单元中编译为两个不同的实现。我想可以通过结构体的 gdb 内存 repr 内的
ptype /o unti1.cpp::MyStruct
命令进行检查,并检查它是否与 unit2.cpp::MyStruct 相同。Google led me here for "undefined non-virtual thunk"
I really want to mention this for others (as I spent almost half a day to track this issue commenting out code).
In my exact case the cause of this error was unpaired
#pragma pack(push, 4)
without#pragma pack(pop)
around C struct with enforced memory footprint (by protocol spec) in header file which messes up all headers included next.I guess it's rather good not to compile such codebase, then silently builds up executable where units have different memory footprint of the same classes.
So maybe original question may have some sort of the underlying issue, somehow related to binary representation maybe with some different compile flags. So when implementation defined in h the problem gone because it's actually compiles to two different implementation in two different compilation units. I guess it could be possible to inspect by
ptype /o unti1.cpp::MyStruct
command inside gdb memory repr of a struct and check if it's the same as unit2.cpp::MyStruct.