Dun*_*ter 5 c++ constructor compiler-errors g++ vtable
虽然堆栈溢出还有其他问题,这些问题涉及"未定义的vtable引用"错误消息.以下代码编译或不编译,具体取决于no-args构造函数C()是否在线实现.我知道成员函数m()应该是纯虚拟的,并且这是正确的更改,以便解决问题.令我感到困惑的是,它可以通过明显不相关的变化进行编译.
下面的代码不能用g ++编译(在ubuntu 64位上为4.6.3)并产生预期的'未定义的对vtable for C'消息的引用(考虑到m()的问题,记录仍然是一个可怕的错误消息)
Header.h
#ifndef HEADER_H
#define HEADER_H
class C
{
public:
C();
virtual void m();
};
#endif
Run Code Online (Sandbox Code Playgroud)
Implementation.cpp
#include "Header.h"
C::C() {}
Run Code Online (Sandbox Code Playgroud)
Main.cpp的
#include "Header.h"
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下无关的更改允许编译:
为什么这允许编译?这是编译器错误,优化器问题还是标准难题的黑暗角落?
这是编译器错误,优化器问题还是标准难题的黑暗角落?
以上都不是.这不是一个错误,它与优化无关,而且这个特殊问题超出了标准的范围,它由相关的ABI(这只是事实上的标准)所涵盖.
C::m
是关键功能,你没有在任何地方定义它,这意味着编译器不会发出vtable.
代码编译这些更改有很好的(如果复杂的)原因:
- 从Implementation.cpp中删除C :: C()的非内联实现
由于ABI文件2.6中描述的一些复杂原因,在施工期间需要vtable.因此构造函数的定义创建了对vtable的引用,链接器告诉您在链接时缺少该引用.如果删除构造函数的定义,则不会引用vtable.
- 在Header.h中为C()添加琐碎的内联实现
在给定的转换单元中未调用的内联函数将不会在目标文件中发出,因此使函数内联意味着构造函数不在目标文件中,因此目标文件不引用vtable,并且链接器不需要在链接时查找它.
如果改变这样的直列构造实际使用的程序(例如,通过创建一个C
在main
),那么你会回来得到同样的连接错误,因为现在的直列构造函数中定义Main.o
,因此需要的虚函数表.
class C
{
public:
C() { } // inline
virtual void m();
};
int main()
{
C c;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2989 次 |
最近记录: |