C++ MingW4.7.0到4.7.2错误:无效;这";使用混合虚拟和非虚拟多重继承时成员函数中的指针
我有这样的继承代码:C++ MingW4.7.0到4.7.2错误:无效;这";使用混合虚拟和非虚拟多重继承时成员函数中的指针,c++,mingw,multiple-inheritance,virtual-inheritance,C++,Mingw,Multiple Inheritance,Virtual Inheritance,我有这样的继承代码: B / \ / \ / \ BI D (template) / \ / \ / DI (template) [B]ase和[D]erived都是包含静态方法create(),该方法返回各自实现的实例BaseImpl或派生impl。 实现是模板,工厂方法选择如何在运行时实例化它们。下面的代码是我的程序逻辑的工作示例 问题是,在我的真实代码中
B
/ \
/ \
/ \
BI D
(template) /
\ /
\ /
DI
(template)
[B]ase
和[D]erived
都是包含静态方法create()
,该方法返回各自实现的实例BaseImpl
或派生impl
。
实现是模板,工厂方法选择如何在运行时实例化它们。下面的代码是我的程序逻辑的工作示例
问题是,在我的真实代码中,Base
方法得到了一个错误的指针,并且不可避免地崩溃。我在调用其中一个方法之前检查了汇编代码,该方法在实际代码和示例代码中都不带参数,并发现它有所不同:
工作(示例)代码
call <std::unique_ptr<Base, std::default_delete<Base> >::operator->() const>
mov (%eax),%edx
add $0x8,%edx
mov (%edx),%edx
mov %eax,%ecx
call *%edx
call <std::unique_ptr<Base, std::default_delete<Base> >::operator->() const>
mov (%eax),%edx
add $0x18,%edx
mov (%edx),%ebx
lea -0x24(%ebp),%edx
mov %eax,(%esp)
movl $0x9,-0x9c(%ebp)
mov %edx,%ecx
call *%ebx
这是完全相同的base->method()
调用。method()
的地址这次存储在ebx
中但是,此
是从堆栈外的任意位置加载的!?正如预期的那样,程序崩溃了。有人知道编译器为什么会生成这样的程序集吗?我还在想办法
代码
下面是示例代码。真正的代码在一个类似于示例从invoker->invoke()
调用base->check()
的点崩溃
删除代码以节省空间。要查看它,请检查编辑历史记录。这是一个错误。(,)该错误特定于gcc-i686-mingw
版本4.7.0
至4.7.2
发件人:
当对同时使用虚拟继承和非虚拟继承的对象调用虚拟调用时,虚拟thunk将使用无效的“this”指针离开目标函数
这基本上就是我在问题中描述的。应保存此
的寄存器用于非相关操作
唯一的解决方案是降级到4.7.0以下或升级到4.7.3
或更高。此指针的可能副本不必在不同的派生类中保持不变。如果您需要最外层对象的基址,可以使用dynamic\u cast
iirc.@AlanStokes是的,您完全正确。我发布的代码没有重现我在真实代码中的错误。实际代码中这个指针的地址超出了程序虚拟内存的范围,例如0x429bce8
vs0x7a55ec
。我会设法弄清楚发生了什么事。我已经更新了问题。@n.m.它不是重复的。