0

私はすでにhttp://www.cplusplus.com/forum/general/96128/でこの質問をしましたが、役に立ちませんでした。

g++ 4.2 で同じバグを経験した人はいますか?internal compiler error: in make_thunk, at cp/method.c:129

サンプルコードを含める必要はないと思います。それぞれのコードは、clang++ だけでなく、他のいくつかの新しい g++ バージョンでも警告やエラーなしでコンパイルされます。それは単に正しいことであり、バグは GCC の bugzilla で言及されていました (頻繁に再発するように見えるため、数回も) が、回避策は提供されませんでした。

新しい g++ を使用するように言わないでください。Ubuntu Hardyに同梱されている g++ でコンパイルする必要があるため、コンパイラを変更することはできません主な開発は Ubuntu Precise で行っていますが、Hardy との互換性を維持する必要があります。

サンクがどうあるべきかわかりません。共変や多重継承に関係していると思われるだけです。また、Hardy のコンパイラのバグのために、名前がクラスの名前であるという唯一の変更にもかかわらず、私はそれを変更する目的がありません。

もう 1 つの事実は、インクルード時に発生することです。

In file included from /home/heiko/hgl/src/compiler/compilerprojectfactory.cpp:18:
/home/heiko/hgl/src/compiler/compilertype.h: In instantiation of 'HGL::Compiler::CompilerType<HGL::Vector2D, HGL::Compiler::CompilerBase>':
/home/heiko/hgl/src/compiler/compilervector2d.h:23: instantiated from here
/home/heiko/hgl/src/compiler/compilertype.h:22: internal compiler error: in make_thunk, at cp/method.c:129
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see <URL:file:///usr/share/doc/gcc-4.2/README.Bug

編集: ここで、バグの原因となるヘッダー:

#include "compilertype.h"
#include "vector2d.h"

namespace HGL {

class Vector2D;

namespace Compiler {

/**
    @author Heiko Schäfer <heiko@rangun.de>
*/
class _LOCAL Vector2D : public Compiler::CompilerType<HGL::Vector2D> {
    DISALLOW_COPY_AND_ASSIGN(Vector2D)
public:
    Vector2D(float x, float y, int line);

    using IType::operator=;

    virtual operator HGL::Vector2D &() const throw(InvalidExpressionException);
protected:
    virtual ~Vector2D();

    void append(ISerializeable::BUFFER *dest, const HGL::IType *type) const;
};

}

}

テンプレートは次のとおりです。

#include "compilerbase.h"
#include "iproject.h"
#include "util.h"

namespace HGL {

namespace Compiler {

const IProject::VSTRUCT minReq = { HGL_MINREQ_MAJOR, HGL_MINREQ_MAJOR, HGL_MINREQ_MAJOR };

template<class Type, class Base = CompilerBase>
class _LOCAL CompilerType : public Type, public Base {
    DISALLOW_COPY_AND_ASSIGN(CompilerType)
public:
    using IType::operator=;

    template<class Param>
    inline CompilerType(const Param &p, bool b, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) :
        Type(p), Base(line, b) {
        init(vs);
    }

    template<class Param>
    inline CompilerType(const Param &p, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(p), Base(line) {
        init(vs);
    }

    inline CompilerType(bool b, int line, const IProject::VSTRUCT &vs = IProject::VSTRUCT())
        : Type(), Base(line, b) {
        init(vs);
    }

    template<class Param1, class Param2>
    inline CompilerType(const Param1 &p1, const Param2 &p2, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) :
        Type(p1, p2), Base(line) {
        init(vs);
    }

    template<class Param1, class Param2>
    inline CompilerType(const Param1 &p1, const Param2 &p2, bool b, int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(p1, p2),
        Base(line, b) {
        init(vs);
    }

    inline CompilerType(int line,
                        const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(), Base(line) {
        init(vs);
    }

    inline virtual void append(ISerializeable::BUFFER *dest, const IType *type) const {
        Base::append(dest, type);
    }

protected:
    inline virtual ~CompilerType() {}

    inline virtual void init(const IProject::VSTRUCT &vs) {
        const_cast<IProject::VSTRUCT &>(vs) = std::max(vs, minReq);
        CompilerBase::setMinRequiredVersion(vs, Type::getSerialID());
    }

};

}

}

解決しました!

g++ 4.2 のソース コードを掘り下げた後、完全なツリー内のすべての型について今必要であることがわかりました。g++ > 4.2 は明らかにこれを必要としません。

したがって、エラーは、転送された特殊化を持つテンプレート メンバーを持つ関連クラスにありました。転送の代わりにヘッダーを含めただけで、g++ 4.2 は満足でした。

それ以外の場合、エラーを出さないのは本当に良くないバグですが、この役に立たないメッセージです。

4

1 に答える 1

1

サンクまたはトランポリンは、動的ディスパッチの一部の実装で追加されるコードの一部であり、使用される最終オーバーライドに関して基本仮想関数のインターフェイスを適応させます。あなたが言及したように、一般的にthis、複数/仮想継承でポインターを適応させ(最初の空でないものの後にリストされたベースの場合)、結果のポインター/参照を共変の戻り値の型に適応させる必要があります。

このエラーは、コンパイラのバグであることを示しています。その特定のコンパイラを使用する必要がある場合は、問題を回避する必要があり、それには設計の変更が伴います。複数/仮想継承の使用を制限したり、リスト内のベースを並べ替えたり、コンパイラーがそのコードを何らかの方法で消化できるようになるまでいろいろ試してみることができます。共変の戻り値の型のアダプターを生成するときに問題になる場合は、共変の戻り値を削除し、共変の型を返す (別の名前で) オーバーロードを提供することを検討してください (つまり、共変の戻り値を非仮想関数に置き換えて、最も多くの値を返す)。派生型と、前のものを呼び出してベースへの参照を返す仮想関数)。

これらの一般的なヒント以外に、コードとコンパイラの実装を見なければ、他に言うことはほとんどありません。

于 2013-03-18T19:13:42.490 に答える