6

コードでリンカ エラーが発生します。私はそれを以下の最低限の必需品に絞り込みました.

このコードは、次から参照されるリンカ エラー「Foo の vtable」を示します: Foo::Foo()

class Foo {
public:
  Foo();
  virtual ~Foo() = default;
};
Foo::Foo() { }

しかし、このコードではエラーは発生しません。

class Foo {
public:
  Foo();
  virtual ~Foo() { }
};
Foo::Foo() { }

なんで?= defaultは基本的に空の角括弧と同じことをするはずだと思いました。

更新: Xcode 4.5.2 の一部である「Apple LLVM コンパイラ 4.1」を使用しています。このコンパイラのバグでしょうか?最新の GCC で動作する可能性があります (ただし、Apple はもう出荷していません)。コンパイラに関する議論については、以下のコメントを参照してください。

更新 2:以下で説明するように、行を に変更するとvirtual inline ~Foo() = default;、このエラーが解消されます。これは単にバグである必要はありませんか?この場合、明示的に書き出さない限り、コンパイラはインライン関数を認識しないようinlineです。

4

3 に答える 3

3

これは、すでに修正されている clang のバグのようです。新しいリリースが間もなく来るはずなので、あなたは良いタイミングで尋ねました:リリース候補はすでに利用可能です. あなたの例は i386-linux バイナリ リリースで動作し、それらすべてで動作するはずです。

于 2012-12-15T22:32:27.627 に答える
2

Itanium ABI では、クラス内でインラインで定義されていない最初の仮想メソッドの定義を含む変換単位の v-table (およびその他の RTTI 情報) が生成されるか、インラインで定義された仮想メソッドしかない場合は、すべての変換単位について出力されます。それにはクラスが含まれます。冗長なシンボルをマージするのはリンカー次第です。

を指定することにより= default、Clang は、クラスでメソッドをインラインで定義したこと、およびファイルを含むすべての TU が v-table と RTTI 情報を定義する必要があることを認識せず代わりvirtualに定義が表示されるのを待機している可能性があります。どこか。

定義をクラスの外に置くことをお勧めしますか? =>Foo::~Foo() = default;

于 2012-12-15T15:54:53.297 に答える
1

g++ 4.7.2 で動作します。しかし、私はclang 3.1であなたと同じ問題を抱えています。

私は3つのファイルを持っています。

フー.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にバグがあると思います。

于 2012-12-15T11:53:27.440 に答える