Compiler Warning (level 1) C4407

cast between different pointer to member representations, compiler may generate incorrect code

An incorrect cast was detected.

C4407 can be generated because of compiler conformance work that was done in Visual C++ 2005. Pointer-to-member now requires a qualified name and the address-of operator (&).

C4407 can occur if you cast between a multiple inheritance pointer-to-member to a single inheritance pointer-to-member. Sometimes this can work, but sometimes it can’t because the single inheritance pointer-to-member representation doesn’t hold sufficient information. Compiling with the /vmm might help (for more information, see /vmm, /vms, /vmv (General Purpose Representation)). You can also try rearranging your base classes; the compiler is detecting a loss of information in the conversion because a base class is at a non-zero offset from the derived.

The following sample generates C4407:

// C4407.cpp
// compile with: /W1 /c
struct C1 {};
struct C2 {};
struct C3 : C1, C2 {}; /** 这里如果交换C2与C1的顺序即可消除警告 */

typedef void(C3::*PMF_C3)();
typedef void(C2::*PMF_C2)();

PMF_C2 f1(PMF_C3 pmf) {
   return (PMF_C2)pmf;   // C4407, change type of cast,
   // or reverse base class inheritance of C3 (i.e. : C2, C1)
}

这两天在用cocos2d-x在写游戏,里面有些类似下面的代码:
struct CCObject
{
  typedef void (CCObject::*pmfn)(float);

CCObject* _obj;
  pmfn _pmfn;

void some_func(CCObject* obj, pmfn fn)
  {
    _obj = obj;
    _pmfn = fn;
  }

  void exec()
{
(_obj->*_pmfn)(1.0f);
}
}

struct some_sub
  : public CCObject
{
  void _init()
  {
    some_func(this, (CCObject::pmfn)&some_sub::some_callback);
  }

  void some_callback(float)
  {
  }
};

目前,上面的代码是没有任何bug的,因为在some_sub::_init方法中,this的值与隐式转换后的CCObject*是相等的。
但是,在引入多重继承后,可能会出现Bug,因为this指针与转换后的CCObject*可能会不相等(与继承列表顺序有关),此时some_callback这个函数还是会被调用,但是这个成员函数的this参数确是错的!你以为你在some_callback中修改的是成员变量的值,实际上这时候可能已经内存越界了,谁知道你改写了哪个对象的内存。

转载于:https://www.cnblogs.com/avexer/p/3258294.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值