2013-03-18 69 views
0

我问已经在http://www.cplusplus.com/forum/general/96128/但无济于事这个问题。克++ 4.2:内部编译器错误:在make_thunk,在CP/method.c:129

是否有人经历了G ++ 4.2相同的错误:internal compiler error: in make_thunk, at cp/method.c:129

我想时并不需要包括示例代码。相应的代码在几个其他较新的g ++版本以及clang ++上编译时没有警告和错误。这只是正确的,并且在GCC的bugzilla中提到了这个错误(甚至几次,因为它似乎经常重演),但没有提供解决方法。

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

我不知道一个thunk应该是,我只是怀疑它与协变量和/或多重继承的事。另外我还有几个更类似的结构化头文件,它们都编译得很好,尽管唯一的变化是名称是类的名称,我没有目标,因为哈代上的编译器错误而改变了这一点。

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

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 <[email protected]> 
*/ 
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很高兴。

否则,它确实是一个不漂亮的错误不给一个错误,但这没用消息。

+0

它*是*必须包含代码。最好提供一个[SSCCE](http://sscce.org/)。 – 2013-03-18 18:47:19

+0

我现在无法访问gcc 4.2,但是'_LOCAL'与它有什么关系?以'_'开头的名字被保留用于实现,所以你可能会在一些内部的g ++东西上行走。 – juanchopanza 2013-03-18 19:04:03

+0

你应该将它降低到SCCEE,这可能已经帮助你自己解决问题。我的猜测是你的实例化顺序有问题,因为较早的GCC在阶段1实例化了一些类而不是阶段2 AFAIR。但是看不到一些碎片是不可能的,所以...... SSCCE现在是你的功课;) – 2013-03-18 19:04:18

回答

1

蹦床是一块是在动态调度的一些实施方式中加入到基础虚拟函数的界面相对于所述最终超控器适应正在使用的代码。正如你所提到的,通常需要修改多重/虚拟继承中的指针this(用于在第一个非空继承之后列出的基础),并使生成的指针/引用适应协变返回类型。

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

除了那些通用的提示,没有看到你的代码和编译器的实现,没有什么可说的。

+0

感谢至少_thunk_的解释,重新设计是没有问题的。一些几乎相同的接口工作,我现在正在检查_fatal_小差异可能在哪里。 – 2013-03-18 19:33:58

+0

@HeikoSchäfer:记住这是一个编译器错误,你有类似的工作并不意味着编译器会喜欢这个特定的情况,因为可能有些荒谬的表面上毫无关联。 – 2013-03-18 19:41:00

+0

对不起,我的答案不允许+1。如果发现错误的原因,真正的错误是,它是错误的错误信息。我深入研究了g ++代码并试图找出导致这个gcc_assert的原因。我注意到我的帖子下方的解决方案。 – 2013-03-18 19:50:59