dynamic_cast Issues

D

duey

Can anyone explain how this works?

class Test
{
public:
Test() {}

int x;
std::wstring id;

void func() { std::cout << "Calling func" << std::endl; }
};

int main()
{
int junk = 0x6554433;
void* ptr = (void*)junk;

Test* tt = dynamic_cast<Test*>( (Test*)ptr);
if ( tt == NULL )
{
std::cout << "Invalid Test pointer" << std::endl;
}
else
{
std::cout << "Valid Test pointer" << std::endl;
tt->func();
}
return 0;
}

The output is:
Valid Test pointer
Calling func

I would have expected this code to return an invalid pointer.

Thanks,
Kevin
 
I

Ian Collins

Can anyone explain how this works?

class Test
{
public:
Test() {}

int x;
std::wstring id;

void func() { std::cout<< "Calling func"<< std::endl; }
};

int main()
{
int junk = 0x6554433;
void* ptr = (void*)junk;

Test* tt = dynamic_cast<Test*>( (Test*)ptr);

You have lied to the compiler, so all bets are off.
 
T

tonydee

Can anyone explain how this works?

class Test
{
public:
 Test() {}

 int x;
 std::wstring id;

 void func() { std::cout << "Calling func" << std::endl; }

};

int main()
{
 int junk = 0x6554433;
 void* ptr = (void*)junk;

 Test* tt = dynamic_cast<Test*>( (Test*)ptr);
 if ( tt == NULL )
 {
  std::cout << "Invalid Test pointer" << std::endl;
 }
 else
 {
  std::cout << "Valid Test pointer" << std::endl;
  tt->func();
 }
 return 0;

}

The output is:
Valid Test pointer
Calling func

I would have expected this code to return an invalid pointer.

This is undefined behaviour - dynamic_cast<> isn't even valid on types
without virtual functions, and you've compounded that with invalid
pointer dereferences. Still, many compilers choose to provide some
support for dynamic_cast<> on other types, and it's easy for a
compiler seeing...

Test* tt = dynamic_cast<Test*>( (Test*)ptr);

....to realise the template argument <Test*> already matches the
argument type (Test*) and pass the value through without any actual
use of RTTI. Then your dereferencing of an invalid pointer just
happens to hang together on your compiler, presumably because your
func() function is effectively static, so a garbled "this" pointer is
never actually used.

Cheers,
Tony
 
D

duey

This is undefined behaviour - dynamic_cast<> isn't even valid on types
without virtual functions, and you've compounded that with invalid
pointer dereferences.  Still, many compilers choose to provide some
support for dynamic_cast<> on other types, and it's easy for a
compiler seeing...

    Test* tt = dynamic_cast<Test*>( (Test*)ptr);

...to realise the template argument <Test*> already matches the
argument type (Test*) and pass the value through without any actual
use of RTTI.  Then your dereferencing of an invalid pointer just
happens to hang together on your compiler, presumably because your
func() function is effectively static, so a garbled "this" pointer is
never actually used.

Cheers,
Tony

Thanks for the info guys.

Now my next question is there anyway to make this work? We receive
these void* pointers that are supposed to be pointers to the objects
that handle the messages. Sometimes these objects have been deleted
and we need to be able to determine if the pointers are valid before
we start using them (for obvious reasons).
I know that we shouldn't be using void* pointers in the first place
but we're using a legacy library that we really don't want to change
since it affects multiple projects (hardware and software).

Thanks again,
Kevin
 
Ö

Öö Tiib

Thanks for the info guys.

Now my next question is there anyway to make this work? We receive
these void* pointers that are supposed to be pointers to the objects
that handle the messages. Sometimes these objects have been deleted
and we need to be able to determine if the pointers are valid before
we start using them (for obvious reasons).
I know that we shouldn't be using void* pointers in the first place
but we're using a legacy library that we really don't want to change
since it affects multiple projects (hardware and software).

The void* that was taken from actually same object is suitable to be
cast back into real thing.
C style casting you use in mix with C++ style casting in your example
is not too fine. Casting random crap like you did is totally wrong. No
cast does discover if the object has been already deleted or not.

If your legacy library provides such garbage pointers then how is it
used in multiple projects? This thing should crash frequently. I
suspect that the problems are between chair and keyboard and not in
library.
 
J

Jonathan Lee

Sometimes these objects have been deleted
and we need to be able to determine if the pointers are valid before
we start using them (for obvious reasons).

But in trying to determine if they're valid or not, you *are*
using them. And by 3.7.3.2/4, that's undefined behavior.

The only ways I can see around this would be if you used some
kind of garbage collection, or using smart pointers as a level
of indirection on your objects. But who knows how much you
could guarantee with some black box kind of library :/

--Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top