Stack Corruption when passing pointer to member function of a forward referenced class - by StanBlakey

Status : 

  By Design<br /><br />
		The product team believes this item works according to its intended design.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


1
0
Sign in
to vote
ID 311661 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 11/21/2007 10:04:02 AM
Access Restriction Public

Description

Stack Corruption when passing pointer to member function of a forward referenced class.

 

Using Visual C++ Orcas I am getting a stack corruption when I pass a pointer to a member function to a routine where that routine only has a forward reference to the class whose member function is the subject of interest. 

The message when running with the debugger is 
"Run-Time Check Failure #2 - Stack around the variable 'atest2' was corrupted."

When I supply the full header for the class of interest all is well.

It appears as if the callee expects a more to be passed on the stack than the calleer passes if there is only a forward reference. 




I don't get any compiler warnings. 

Any ideas welcome.

 

Regards,
Stan

 

Callee header file

MyTest2.h

 

#ifndef MyTest2_h__

#define MyTest2_h__

class MyTest;

typedef int (MyTest::*t_mbr_fn)(void);

class MyTest2

{

public:

void setup(t_mbr_fn fn);

int run(void);

private:

MyTest* ptrMyTest_;

t_mbr_fn mbr_fn_;

};

 

#endif // MyTest2_h__

 

----------------

Callee cpp file MyTest2.cpp

 

#include "MyTest2.h"

//#include "MyTest.h" // Works when this is not commented out.

class MyTest; // Fails with just a forward declaration. 

void MyTest2::setup(t_mbr_fn fn)

{

mbr_fn_ = fn;

}

int MyTest2::run(void)

{

return (ptrMyTest_->*mbr_fn_)();

}

 

----------------

Caller code 

// test_memfun_passing.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "MyTest.h"

#include "MyTest2.h"

 

int _tmain(int argc, _TCHAR* argv[])

{


MyTest aMyTest;


MyTest2 atest2;

t_mbr_fn fn = &MyTest::getData;

atest2.setup( fn );

return 0;

}

 

--------------------

MyTest.h code

#ifndef MyTest_h__

#define MyTest_h__

 

class MyTest

{

public:

MyTest(void) : data(0) {}

int getData() {return data; }

private:

int data;

};

#endif // MyTest_h__
Sign in to post a comment.
Posted by Microsoft on 11/30/2007 at 9:56 AM
Hi: this is pretty much By-Design. Visual C++ has different representations for pointers-to-members depending on the type of the class hierarchy involved. This was done for performance reasons as a pointer-to-member in a single inheritance hierarchy requires much less "data" than a pointer-to-member in a virtual inheritance hierarchy. In retrospect I suspect this was an optimization too far - it really doesn't save that much space - especially as pointers-to-members are rare and furthermore it leads to problems like you are seeing. There is a solution to your problem: that is to tell the compiler that the forward declaration of the class will only be used in a single-inheritance hierarchy. For example:

class __single_inheritance MyTest;

If you do this you should find that your code will compile and execute correctly.

Jonathan Caves
Visual C++ Compiler Team
Posted by Microsoft on 11/22/2007 at 2:51 AM
Thanks for your feedback. We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you,
Visual Studio Product Team