Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MingW4.7.0到4.7.2错误:无效;这";使用混合虚拟和非虚拟多重继承时成员函数中的指针_C++_Mingw_Multiple Inheritance_Virtual Inheritance - Fatal编程技术网

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
vs
0x7a55ec
。我会设法弄清楚发生了什么事。我已经更新了问题。@n.m.它不是重复的。