C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 27:
[27.11] Why do people worry so much about pointer casts and/or reference casts?

Because they're evil! (Which means you should use them sparingly and with great care.)

For some reason, programmers are sloppy in their use of pointer casts. They cast this to that all over the place, then they wonder why things don't quite work right. Here's the worst thing: when the compiler gives them an error message, they add a cast to "shut the compiler up," then they "test it" to see if it seems to work. If you have a lot of pointer casts or reference casts, read on.

The compiler will often be silent when you're doing pointer-casts and/or reference casts. Pointer-casts (and reference-casts) tend to shut the compiler up. I think of them as a filter on error messages: the compiler wants to complain because it sees you're doing something stupid, but it also sees that it's not allowed to complain due to your pointer-cast, so it drops the error message into the bit-bucket. It's like putting duct tape on the compiler's mouth: it's trying to tell you something important, but you've intentionally shut it up.

A pointer-cast says to the compiler, "Stop thinking and start generating code; I'm smart, you're dumb; I'm big, you're little; I know what I'm doing so just pretend this is assembly language and generate the code." The compiler pretty much blindly generates code when you start casting — you are taking control (and responsibility!) for the outcome. The compiler and the language reduce (and in some cases eliminate!) the guarantees you get as to what will happen. You're on your own.

By way of analogy, even if it's legal to juggle chainsaws, it's stupid. If something goes wrong, don't bother complaining to the chainsaw manufacturer — you did something they didn't guarantee would work. You're on your own.

(To be completely fair, the language does give you some guarantees when you cast, at least in a limited subset of casts. For example, it's guaranteed to work as you'd expect if the cast happens to be from an object-pointer (a pointer to a piece of data, as opposed to a pointer-to-function or pointer-to-member) to type void* and back to the same type of object-pointer. But in a lot of cases you're on your own.)