gcc 4.0, a framework, and dynamic_cast problems
gcc 4.0, a framework, and dynamic_cast problems
- Subject: gcc 4.0, a framework, and dynamic_cast problems
- From: Anton Leuski <email@hidden>
- Date: Sun, 16 Apr 2006 17:57:12 -0700
I've ran into some weird problems while building a framework that
uses dynamic_cast templates. Specifically, it looks like dynamic_cast
may fail depending on whether _some_ of the member functions of a
class from the framework defined as inline or not. And, whether the
function that calls the dynamic_cast is inline or not. A code example
follows and I've also included the project file for the curiously
minded. My questions are
1. is this a bug? it looks like one to me, because everything works
correctly under gcc-3.3.
2. is this is a known problem? Is there a solution?
Thank you
-- Anton
---- example:
5 files. The following 4 make the framework in question.
Note that there is NO difference between testGrandChild and
testGrandChild_OnlyInline except for the function bar() defined when
declared (testGrandChild_OnlyInline ) and defined in a separate file
(testGrandChild). dynamic_cast behavior is very different between two
classes.
Note also how the dynamic_cast fails for an object of testGrandChild
if it is called from an inline function and succeeds if it is called
from a regular context.
// ----------------- test.h
#ifndef __test_h__
#define __test_h__
class test {
public:
virtual ~test() { }
virtual void foo () const = 0;
};
class testChild : public test {
public:
virtual void foo () const { }
};
class testGrandChild : public testChild {
public:
virtual void foo () const { }
virtual void bar () const;
};
class testGrandChild_OnlyInline : public testChild {
public:
virtual void foo () const { }
virtual void bar () const { }
};
#endif // __test_h__
// ----------------- test.cpp
#include "test.h"
void testGrandChild::bar () const { }
// ----------------- caller.h
#ifndef __caller_h__
#define __caller_h__
#include "test.h"
#include <iostream>
using namespace std;
inline void inline_call(const test& t, bool inline_only)
{
cout << "testing for parent: ";
if (const test* tc = dynamic_cast<const test*> (&t)) {
cout << "success!\n"; // doah! sanity check
tc->foo();
} else {
cout << "failure!\n";
}
cout << "testing for child: ";
if (const testChild* tc = dynamic_cast<const testChild*> (&t)) {
cout << "success!\n";
tc->foo();
} else {
cout << "failure!\n";
}
cout << "testing for grand child: ";
if (inline_only) {
if (const testGrandChild_OnlyInline* tc = dynamic_cast<const
testGrandChild_OnlyInline*> (&t)) {
cout << "success!\n";
tc->foo();
} else {
cout << "failure!\n";
}
} else {
if (const testGrandChild* tc = dynamic_cast<const testGrandChild*>
(&t)) {
cout << "success!\n";
tc->foo();
} else {
cout << "failure!\n";
}
}
}
void noninline_call(const test& t, bool inline_only);
#endif // __caller_h__
// ----------------- caller.h
#include "caller.h"
void noninline_call(const test& t, bool inline_only)
{
inline_call(t,inline_only);
}
// ---------------- main.cpp ----
// this is the test file of a Shell tool that uses the framework
#include "caller.h"
#include <iostream>
using namespace std;
int main(int argc, const char* argv[])
{
cout << "Testing RTTI\n";
testGrandChild tc;
testGrandChild_OnlyInline tco;
cout << "\nInline caller for testGrandChild\n";
inline_call(tc,false);
cout << "\nNon Inline caller for testGrandChild\n";
noninline_call(tc,false);
cout << "\nInline caller for testGrandChild_OnlyInline\n";
inline_call(tco,true);
cout << "\nNon Inline caller for testGrandChild_OnlyInline\n";
noninline_call(tco,true);
}
The output is
Testing RTTI
Inline caller for testGrandChild
testing for parent: success!
testing for child: failure!
testing for grand child: success!
Non Inline caller for testGrandChild
testing for parent: success!
testing for child: success!
testing for grand child: success!
Inline caller for testGrandChild_OnlyInline
testing for parent: success!
testing for child: success!
testing for grand child: success!
Non Inline caller for testGrandChild_OnlyInline
testing for parent: success!
testing for child: failure!
testing for grand child: failure!
Attachment:
test.zip
Description: Zip archive
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden