g++4.2:内部编译器错误:在make_thunk中,cp/method.c:129

g++ 4.2: internal compiler error: in make_thunk, at cp/method.c:129

本文关键字:cp method thunk 内部 编译器 错误 make g++4      更新时间:2023-10-16

我已经在上问过这个问题了http://www.cplusplus.com/forum/general/96128/但无济于事。

有人在g++4.2:internal compiler error: in make_thunk, at cp/method.c:129 中遇到过同样的错误吗

我认为没有必要包含示例代码。在其他几个较新的g++版本以及clang++上,相应的代码编译时没有警告和错误。这是完全正确的,GCC的bugzilla中提到了这个错误(甚至好几次,因为它似乎经常重复出现(,但没有提供解决方法。

请不要告诉我也要使用更新的g++。我必须在Ubuntu Hardy附带的g++上编译它,所以我不能更改编译器。主要的开发是在UbuntuPrecise上完成的,但我需要保持它与Hardy的兼容性。

我不知道thunk应该是什么,我只怀疑它与协变和/或多重继承有关。此外,我还有几个更相似的结构化头文件,它们都编译得很好,尽管唯一的变化是名称是类的名称,而且由于Hardy上的编译器错误,我没有改变这一点的目标。

另一个事实是,它发生在包含时间。

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很高兴。

否则,不给出错误,而是给出这个无用的消息,这真的是一个不好的bug。

thunk蹦床是在动态调度的某些实现中添加的一段代码,用于根据所使用的最终覆盖器调整基本虚拟函数的接口。正如您所提到的,通常需要在多重/虚拟继承中调整this指针(对于第一个非空的基之后列出的基(,并使用协变返回类型调整生成的指针/引用。

该错误表明这是一个编译器错误。如果你必须使用特定的编译器,你需要解决这个问题,这将涉及到改变你的设计。您可以尝试限制多重/虚拟继承的使用,对列表中的基重新排序,或者尝试绕过,直到您设法让编译器以某种方式消化代码。如果为协变返回类型生成适配器时出现问题,请考虑删除协变返回并提供一个将返回协变类型的重载(使用不同的名称((即,用返回最派生类型的非虚拟函数和调用前一个并返回对基的引用的虚拟函数替换协变返回(。

除了这些通用提示之外,如果看不到您所拥有的代码和编译器的实现,就没有什么好说的了。