Re: stroustrup, void*, and reinterpret_cast
Greg Herlihy wrote:
andrew_nuss@yahoo.com wrote:
I've noticed that on pg. 342 of Stroustups "C++ Programming Language"
book his example of using partial specialization for a custom vector
template where T is a pointer to anything to avoid bloat, he uses
reinterpret_cast to go back and forth between void* and T* pointers.
Why? Why not use static_cast?
1) he made a mistake (unlikely)
A mistake is indeed unlikely. So logically, we can speculate that using
reinterpret_cast at the time this example was written - was likely not
a mistake in C++.
It's not really a mistake today, since it has the same effect as
static_cast in this context.
Still, Stroustrup is human (and I think he'd be the last to deny
it). Typos occur, and he's not immune to them, any more than
you or I are. He corrected it in later editions; I'd consider
that a recognition on his part that there was a mistake.
2) does static_cast with complicated T* to void* cause
address shifts? If so this could cause problems with
preservation of a NULL value as well as a round-trip
inconsistency. My feeling is that reinterpret_cast simply
will not change the actual pointer value stored from the
assembly perspective in either direction, which is desired.
If changing the actual pointer value is undesirable - why
would a static_cast change the pointer value any more than
reinterpret_cast?
Because it does. Not when casting to and from a void*, but when
casting up and down in an inheritance hierarchy.
A void pointer can be a pointer to any type - so with each
type just as likely as the other, would we not expect either
cast to leave the pointer's value unchanged?
Strictly speaking: the standard does not require that the
address of a non-POD object point to the first byte of that
object; an implementation could place the vptr at the address -
4, or some such. In which case, both reinterpret_cast and
static_cast will change the physical address. (Presumable, in
the case of reinterpret_cast, because of course, all that the
standard requires is that you can cast it to void* and back to
the original type.) In practice, I've never heard of such an
implementation.
[...]
I have no idea of the actual reason - nor do I think the the
issue is particularly significant. But I would guess that - at
the time - the names of the cast operators were not yet final,
so a retroactive "mistake" was always a possibillity once the
cast operators were given names.
The names were finalized very early, if I remember correctly.
On the other hand, our instincts as to which cast is correct
didn't really develope until after that.
Furthermore, choosing one or the other cast won't make any
difference to how the program runs.
But it will affect how a maintenance programmer sees the code.
Which is, in many cases, just as important.
--
James Kanze (Gabi Software) email: kanze.james@neuf.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]