Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What problems could warning C4407 cause?

I got some warnings by using pure virtual interfaces on some MFC CWnd derived objects through multiple inheritance. I believe it's caused by defining the methods which need to be implemented for the message map.

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

That sounds like a bit more than a warning, more like something that might cause heap corruption. So is there another way to do something similar to below that won't cause the MFC dynamic downcast macros to choke anymore than usual?

class ISomeInterface
{
public:
     virtual LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp) = 0;
};

class CSomeCoolWnd : public CWnd, public ISomeInterface
{
public:
     LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp);
};

BEGIN_MESSAGE_MAP(CSomeCoolWnd , CWnd)
     ON_REGISTERED_MESSAGE(WM_USER_DEFINED, &CSomeCoolWnd::OnSomeRegisteredMessage)
END_MESSAGE_MAP()

The only thing I've come up with is commenting out the message handlers from the interfaces and leaving comments telling the consumer that they should implement them. However it would be nice to enforce that through a compiler error rather than letting them use an interface and get unexpected results at runtime from things being missing.

like image 445
AJG85 Avatar asked Sep 26 '11 23:09

AJG85


2 Answers

An excellent description of the different representations of pointer-to-member values can be found at the article Member Function Pointers and the Fastest Possible C++ Delegates. Essentially, all the different inheritance types can require the use of different member function pointer representations. This is compiler-specific and the article talks about a number of different compilers (up to 2005 when the article was written).

Evidently your use of multiple inheritance with virtual functions may require a different representation than a simple pointer-to-member function. There's probably a cast somewhere in ON_REGISTERED_MESSAGE() that isn't visible in the code you posted.

like image 108
Greg Hewgill Avatar answered Nov 04 '22 10:11

Greg Hewgill


Try to use something like this:

class ISomeInterface
{
public:
     virtual LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp) = 0;
};

class CSomeCoolWnd : public CWnd, public ISomeInterface
{
public:
     LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp);
};

typedef void (CSomeCoolWnd::*FNMETHOD) (WPARAM, LPARAM);
FNMETHOD method = &CSomeCoolWnd::OnSomeRegisteredMessage;

BEGIN_MESSAGE_MAP(CSomeCoolWnd, CWnd)
     ON_REGISTERED_MESSAGE(WM_USER_DEFINED, method)
END_MESSAGE_MAP()
like image 42
hired777 Avatar answered Nov 04 '22 10:11

hired777