Re: Safely casting pointer types, purpose of static_cast, etc.
On Jun 5, 1:21 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote:
There have been some recent threads about casting pointers to
and from void* that have me rethinking some of my usual
practices. I have a couple of questions.
1. What is the purpose of C++'s static_cast<>?
To limit the types of casts which can be done. You can't
accidentally cast away const with it, for example. More
importantly, in a class hierarchy, a C style cast is a
static_cast if it is to a base or a derived, but a
reinterpret_cast (i.e. type punning) if it is to a sibling. (An
attempt to use static_cast in this case will cause compiler
error.) Also, static_cast (and dynamic_cast) respect the access
specifiers in an inheritance hierarchy; C style casts don't.
In other words, is there any real difference between
statements like (with non-pointer types):
Unless the types are pointers or references in an inheritance
hierarchy, there is not difference between a C style cast and a
static_cast, *if* the static_cast is legal. For non-pointer and
non-reference types, in fact, most code I've seen doesn't use
static_cast, but rather the function style casts, e.g.:
"MyClass( 43 )".
double a = 3.4;
int b = (int)a; // <--- this
int c = static_cast<int>(a); // <---
These two are totally indentical. Conceptually, I tend to think
of this as creating a new temporary object, rather than
accessing an existing object through a different type. In such
cases, I'll use a function style cast, or a C style cast with
the argument in parentheses, i.e. "int( a )" or "(int)( a )".
(The latter is necessary if the typename is not a single token,
e.g. "unsigned char".) In my mind, this is the syntax for
"creating a new, temporary object".
(Technically, a pointer cast also creates a new, temporary
object. But the new object is a pointer, and of course, for the
most part, when you use a pointer cast, you're concerned about
the access through the pointer.)
2. What about static cast with void*'s and pointers to class
types, is there any difference here, and also, are these
conversions all safe:
Object *a = new Object;
void *b = a;
Object *c = (Object *)b;
Object *d = static_cast<Object *>(b);
In that code is there any difference between the conversion
when initializing c and d? And, are c/d guaranteed to be valid
pointers to the same object a points to?
No difference, and yes. You can convert any pointer type to
void*, and convert it back *to* *the* *same* *type* without loss
of information. (Note that this more or less implies that void
pointers will be at least as large as any other pointer type.)
3. If c/d are not guaranteed to be valid pointers,
Irrelevant, because they are. I'd use static_cast in this case.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34