views:

1607

answers:

5

Both static_cast and reinterpret_cast seem to work fine for casting void* to another pointer type. Is there a good reason to favor one over the other?

+10  A: 

You should use a reinterpret_cast, because that describes better what you're doing (completely ignoring type safety)

This does actually not describe the effect of a reinterpret_cast. Rather, reinterpret_cast has a number of meanings, for all of which holds that “the mapping performed by reinterpret_cast is implementation-defined.” [5.2.10.3]

However, this is not what happens in this particular case, where the mapping is well-defined by the standard, namely assigning a type to a typeless pointer without changing its address.

This is a reason to prefer static_cast.

Additionally, and arguably more important, is the fact that every use of reinterpret_cast is downright dangerous because it converts anything to anything else really (for pointers), while static_cast is much more restrictive, thus providing a better level of protection. This has already saved me from bugs where I accidentally tried to coerce one pointer type into another.

Konrad Rudolph
In theory you're right on your first point, reinterpret_cast is not well-defined. In practice any implementation will do the same in both cases. IMO, the most self-documenting way should be preferred in that case and IMO that is reinterpret_cast.
Leon Timmermans
@Leon: why is it more self-documenting?
jalf
I guess that's personal, though I must admit I've been converted since posting that to static_cast too :-)
Leon Timmermans
A: 

This is a tough question. On the one hand, Konrad makes an excellent point about the spec definition for reinterpret_cast, although in practice it probably does the same thing. On the other hand, if you're casting between pointer types (as is fairly common when indexing in memory via a char*, for example), static_cast will generate a compiler error and you'll be forced to use reinterpret_cast anyway.

In practice I use reinterpret_cast because it's more descriptive of the intent of the cast operation. You could certainly make a case for a different operator to designate pointer reinterprets only (which guaranteed the same address returned), but there isn't one in the standard.

Nick
A: 

My personal preference is based on code literacy like this:

void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();

or

typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();

They both do the same in the end, but static_cast seems more appropriate in a middle-ware, app enviroment, while reinterpret cast seems more like something you'd see in a lower-level library IMHO.

Robert Gould
+9  A: 

You should not use reinterpret_cast. Casting some pointer from void* is not allowed using reinterpret_cast (5.2.10/7 since void is not an object type. IMHO that's a valid way to read it, even if some compilers do not diagnose it). reinterpret_cast can be used to cast between some unrelated pointer types when writing platform dependent code when necessary.

A pointer to an object can be explicitly converted to a pointer to an object of different type. Except that converting an rvalue of type "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

When you want to cast from void* to something else, you can use static_cast. The Standard explicitly allows this. Converting from one type to another (not the same) type using void* in between will yield to an unspecified pointer value. However, sometimes when you need to write platform dependent code, this can't be avoided.

An rvalue of type "pointer to cv void" can be explicitly converted to a pointer to object type. A value of type pointer to object converted to “pointer to cv void” and back to the original pointer type will have its original value.

Johannes Schaub - litb
A: 

I suggest using the weakest possible cast always.

reinterpret_cast is may be used to cast a pointer to a float. The more structure-breaking cast is, the more attention using it requires.

In case of char*, I'd use c-style cast, until we have some reinterpret_pointer_cast, because it's weaker and nothing else is sufficient.

Pavel Radzivilovsky