我的代码中出现了链接器错误。我已经确定了下面的基本要点。
此代码为链接器提供错误“vtable for Foo”,引自:Foo :: Foo()
class Foo {
public:
Foo();
virtual ~Foo() = default;
};
Foo::Foo() { }
但是这段代码没有任何错误:
class Foo {
public:
Foo();
virtual ~Foo() { }
};
Foo::Foo() { }
为什么呢?我认为= default
基本上与那些空方括号基本相同。
更新:我使用的是“Apple LLVM编译器4.1”,它是Xcode 4.5.2的一部分。它可能是这个编译器中的错误吗?它可能适用于最新的GCC(Apple不再发售)。有关编译器的讨论,请参阅下面的评论。
更新2:如下所述,将行更改为virtual inline ~Foo() = default;
可以消除此错误。难道这只是有成为一个错误吗?在没有明确写出inline
的情况下,看起来编译器无法识别内联函数。
答案 0 :(得分:3)
It appears to be a bug in clang which has been fixed already.您在很短的时间内问过,因为新版本应该很快就会发布:release candidates are already available。请试一试,您的示例适用于i386-linux二进制版本,并且应该适用于所有这些版本。
答案 1 :(得分:2)
在Itanium ABI中,为包含第一个未在类中内联定义的虚拟方法的定义的转换单元发出v表(和其他RTTI信息),或者如果只有内联定义的虚方法,则为每个包含该课程的翻译单元。然后由链接器合并冗余符号。
有可能通过指定= default
,Clang没有意识到您在课程中内联了定义 virtual
方法,并且包含您的每个TU file应该定义v-table和RTTI信息,而是等待定义出现在某个地方。
我可以建议将定义在之外吗? => Foo::~Foo() = default;
答案 2 :(得分:1)
它适用于g ++ 4.7.2。但我和clang 3.1有同样的问题。
我有3个文件。
foo.h中:
#ifndef FOO_H
#define FOO_H
class Foo {
public:
Foo();
virtual ~Foo() = default;
};
#endif // FOO_H
Foo.cpp中:
#include "Foo.h"
Foo::Foo() { }
main.cpp中:
#include <iostream>
#include "Foo.h"
using namespace std;
int main()
{
Foo foo;
return 0;
}
但如果是这样的话,它也适用于clang:
Foo.cpp为空。
的main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
Foo::Foo() { }
int main()
{
Foo foo;
return 0;
}
所以我猜clang在生成目标文件时有错误。