By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,159 Members | 945 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,159 IT Pros & Developers. It's quick & easy.

dynamic_cast between unrelated types

P: n/a
Hello,

first, I didn't find any reference to my question through googling.

dynamic_cast uses RTTI to determine if the cast expression is valid.
Invalid casts of pointers give a '0'-result. As it is the case in the
following example:

-----------------------------------------------------------
#include <iostream>

struct A {virtual void print() {std::cout << "A" << std::endl;}};
struct B {virtual void print() {std::cout << "B" << std::endl;}};
int main(int argc,char* argv[])
{
A* a = new A();
B* b = dynamic_cast<B*>(a);
if (b)
b->print();
else
std::cout << "b is 0" << std::endl;
return 0;
}
-------------------------------------------------------------

This compiles just fine with MS C++ 7, g++ 3.3.3. Running this tells me
(quite correctly) that "b is 0".

What I really don't get is - why isn't this detected at compile time? OK,
that's what static_cast does (replacing the dynamic_cast with a
static_cast in the example gives a nice compiler error).

Scott Meyers advises to prefer compile time errors to run time errors. So
naive reasoning tells me to prefer static_cast, whenever possible.

So here's the question: Can anybody tell me when to prefer dynamic_cast
to static_cast? Are there any possible situations where static_cast
doesn't really work and you have to use dynamic_cast?

Regards
Thomas
Jul 23 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
* Thomas Lorenz:
Hello,

first, I didn't find any reference to my question through googling.

dynamic_cast uses RTTI to determine if the cast expression is valid.
Invalid casts of pointers give a '0'-result. As it is the case in the
following example:

-----------------------------------------------------------
#include <iostream>

struct A {virtual void print() {std::cout << "A" << std::endl;}};
struct B {virtual void print() {std::cout << "B" << std::endl;}};
int main(int argc,char* argv[])
{
A* a = new A();
B* b = dynamic_cast<B*>(a);
if (b)
b->print();
else
std::cout << "b is 0" << std::endl;
return 0;
}
-------------------------------------------------------------

This compiles just fine with MS C++ 7, g++ 3.3.3. Running this tells me
(quite correctly) that "b is 0".

What I really don't get is - why isn't this detected at compile time?
It probably is.

And with non-polymorphic types you'd get a compile time error.

With polymorphic types, however, the language allows this because the
pointer 'a' might be a pointer to the 'A' subobject of an object of a
class that inherits from both 'A' and 'B':

#include <iostream>

struct A {virtual void print() {std::cout << "A" << std::endl;}};
struct B {virtual void print() {std::cout << "B" << std::endl;}};
struct C: A, B {};

int main()
{
A* a = new C();
B* b = dynamic_cast<B*>( a );
if (b)
b->print();
else
std::cout << "b is 0" << std::endl;
return 0;
}
OK,
that's what static_cast does (replacing the dynamic_cast with a
static_cast in the example gives a nice compiler error).

Scott Meyers advises to prefer compile time errors to run time errors. So
naive reasoning tells me to prefer static_cast, whenever possible.
That's not naive, that's very good.

So here's the question: Can anybody tell me when to prefer dynamic_cast
to static_cast? Are there any possible situations where static_cast
doesn't really work and you have to use dynamic_cast?


When you don't know the types at compile time, and a virtual function doesn't
solve the problem (virtual functions perform safe downcasts for you).

Perhaps the most typical example is to apply an event E to an object O, where
you don't know whether O supports event E or not.

In such cases it's preferable to centralize the dynamic casts instead of
having such casts scattered around the code, and one way of centralizing them
is to use the "visitor pattern" (google).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #2

P: n/a
In general you use static_cast when you want to convert numeric data
types such as enums to ints or ints to floats, and you are certain of
the data types involved in the conversion. static_cast conversions are
not as safe as dynamic_cast conversions, because static_cast does no
run-time type check, while dynamic_cast does. A dynamic_cast to an
ambiguous pointer will fail, while a static_cast returns as if nothing
were wrong; this can be dangerous. Although dynamic_cast conversions
are safer, dynamic_cast only works on pointers or references, and the
run-time type check is an overhead.

Saurabh Aggrawal

Jul 23 '05 #3

P: n/a
"Saurabh Aggrawal" <ga*****@hotmail.com> wrote in
news:11**********************@z14g2000cwz.googlegr oups.com:
In general you use static_cast when you want to convert numeric data
types such as enums to ints or ints to floats, and you are certain of
the data types involved in the conversion. static_cast conversions are
not as safe as dynamic_cast conversions, because static_cast does no
run-time type check, while dynamic_cast does. A dynamic_cast to an
ambiguous pointer will fail, while a static_cast returns as if nothing
were wrong; this can be dangerous. Although dynamic_cast conversions
are safer, dynamic_cast only works on pointers or references, and the
run-time type check is an overhead.

Saurabh Aggrawal


OK, that's perfectly understandable. But why isn't dynamic_cast allowed
to do some type checking at compiletime, as static_cast does? My example
code provides the compiler with enough information to decide that the
cast won't work.

And I really can't envision a commonplace scenario containing a line like
DestType* dest = dynaic_cast<DestType*>(src);
where the compiler doesn't know about DestType. OK, DestType could be
void, but those are scenarios I reallly don't want to think about :)

Regards
Thomas
Jul 23 '05 #4

P: n/a
Thomas Lorenz schrieb:
"Saurabh Aggrawal" <ga*****@hotmail.com> wrote in
news:11**********************@z14g2000cwz.googlegr oups.com:

In general you use static_cast when you want to convert numeric data
types such as enums to ints or ints to floats, and you are certain of
the data types involved in the conversion. static_cast conversions are
not as safe as dynamic_cast conversions, because static_cast does no
run-time type check, while dynamic_cast does. A dynamic_cast to an
ambiguous pointer will fail, while a static_cast returns as if nothing
were wrong; this can be dangerous. Although dynamic_cast conversions
are safer, dynamic_cast only works on pointers or references, and the
run-time type check is an overhead.
Yes and no. There are situations when a static_cast on a class/struct
pointer or reference is needed and perfectly safe and so the overhead of
dynamic_cast is completely wasted. Limiting its use to basic types is a
little too strict.
OK, that's perfectly understandable. But why isn't dynamic_cast allowed
to do some type checking at compiletime, as static_cast does? My example
code provides the compiler with enough information to decide that the
cast won't work. Have you read Alf's reply? It shows one such example. A compiler error
in your example case would be logical, but not really worth the effort
given that in almost no real world code, the assignment to the source
pointer/reference is made in a place visible to the compiler at the
point of the cast, so it cannot check whether the conversion might
possibly succeed or not.
And I really can't envision a commonplace scenario containing a line like
DestType* dest = dynaic_cast<DestType*>(src);
where the compiler doesn't know about DestType. OK, DestType could be
void, but those are scenarios I reallly don't want to think about :)

As Alf wrote, the dynamic type of src could be convertible to DestType*
even if src's static type doesn't suggest it is.

Cheers,
Malte
Jul 23 '05 #5

P: n/a
Malte Starostik <ma***@starostik.de> wrote in
news:42********@olaf.komtel.net:

[snip]
There are situations when a static_cast on a class/struct
pointer or reference is needed and perfectly safe and so the overhead
of dynamic_cast is completely wasted. Limiting its use to basic types
is a little too strict.
Yes, that sounds very reasonable, and this is the path I've already
taken.

[snip] Have you read Alf's reply? It shows one such example. A compiler
error in your example case would be logical, but not really worth the
effort given that in almost no real world code, the assignment to the
source pointer/reference is made in a place visible to the compiler at
the point of the cast, so it cannot check whether the conversion might
possibly succeed or not.

No, obviously not ;) His example makes the behaviour of dynamic_cast
perfectly clear.

Thanks for all the help!
Thomas
Jul 23 '05 #6

P: n/a
Thomas Lorenz wrote:

Malte Starostik <ma***@starostik.de> wrote in
news:42********@olaf.komtel.net:

[snip]
There are situations when a static_cast on a class/struct
pointer or reference is needed and perfectly safe and so the overhead
of dynamic_cast is completely wasted. Limiting its use to basic types
is a little too strict.


Yes, that sounds very reasonable, and this is the path I've already
taken.

[snip]
Have you read Alf's reply? It shows one such example. A compiler
error in your example case would be logical, but not really worth the
effort given that in almost no real world code, the assignment to the
source pointer/reference is made in a place visible to the compiler at
the point of the cast, so it cannot check whether the conversion might
possibly succeed or not.

No, obviously not ;)


The problem is that the compiler can not *always* diagnose that.
Most compiler writers, and I am with them on that issue, think that
diagnosing a problem only *sometimes* creates a false sense of security.
Only if a potential problem can be analysed in each and every case, a
warning or an error is something to think about.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #7

P: n/a
"Saurabh Aggrawal" <ga*****@hotmail.com> wrote in
news:11**********************@z14g2000cwz.googlegr oups.com:
In general you use static_cast when you want to convert numeric data
types such as enums to ints or ints to floats, and you are certain of
the data types involved in the conversion. static_cast conversions are
not as safe as dynamic_cast conversions, because static_cast does no
run-time type check, while dynamic_cast does. A dynamic_cast to an
ambiguous pointer will fail, while a static_cast returns as if nothing
were wrong; this can be dangerous. Although dynamic_cast conversions
are safer, dynamic_cast only works on pointers or references, and the
run-time type check is an overhead.


OK, that's perfectly understandable. But why isn't dynamic_cast allowed
to do some type checking at compiletime, as static_cast does? My example
code provides the compiler with enough information to decide that the
cast won't work.

And I really can't envision a commonplace scenario containing a line like
DestType* dest = dynaic_cast<DestType*>(src);
where the compiler doesn't know about DestType. OK, DestType could be
void, but those are scenarios I reallly don't want to think about :)

Regards
Thomas
Jul 23 '05 #8

P: n/a
"Saurabh Aggrawal" <ga*****@hotmail.com> wrote in
news:11**********************@z14g2000cwz.googlegr oups.com:
In general you use static_cast when you want to convert numeric data
types such as enums to ints or ints to floats, and you are certain of
the data types involved in the conversion. static_cast conversions are
not as safe as dynamic_cast conversions, because static_cast does no
run-time type check, while dynamic_cast does. A dynamic_cast to an
ambiguous pointer will fail, while a static_cast returns as if nothing
were wrong; this can be dangerous. Although dynamic_cast conversions
are safer, dynamic_cast only works on pointers or references, and the
run-time type check is an overhead.

Saurabh Aggrawal


OK, that's perfectly understandable. But why isn't dynamic_cast allowed
to do some type checking at compiletime, as static_cast does? My example
code provides the compiler with enough information to decide that the
cast won't work.

And I really can't envision a commonplace scenario containing a line like
DestType* dest = dynaic_cast<DestType*>(src);
where the compiler doesn't know about DestType. OK, DestType could be
void, but those are scenarios I reallly don't want to think about :)

Regards
Thomas
Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.