[Bug c++/14827] Run time error, breaking of type info and static casts

giovannibajo at libero dot it gcc-bugzilla@gcc.gnu.org
Mon Apr 5 15:36:00 GMT 2004


------- Additional Comments From giovannibajo at libero dot it  2004-04-05 15:36 -------
> "The compiler cannot assume anything about the memory pointed to by a void*.
> This implies that dynamic_cast - which must look into an object to determine 
its
> type - cannot cast from a void*. For that, a static_cast is needed. For 
example:
> Radio* f(void* p)
> {
>   Storable* ps = static_cast<Storable*>(p);  // trust the programmer
>   return dynamic_cast<Radio*>(ps);
> }
> " (finish of citation)

> And looking at the previous example just at the same page in this boook we can
> read the comment: "Storable is virtual base of Radio". So, it looks like that
> conversion of pointer to void* (may be implicit at calling this function, or
> explicit, but this should not make differencce, do you agree?) by the opinion 
of
> the creator of this language should not destroy the object and its type and
> should allow later correct static casts of pointer to the base type. This is
> valid even for virtual base class. Could you comment this, please?

You're still wrong, and you are trying to make your book say something it does 
not. If you look carefully at the example you posted from the book, you will 
see that the cast chain is like this: Storable* -> void* -> Storable* -> 
Radio*. In your code, you do like this: SuperDerived* -> void* -> Derived*. You 
cannot do this.

The book explains you why: "The compiler cannot assume anything about the 
memory pointed to by a void*.". The compiler will have to trust the programmer 
(as the comment in the example says) and blindly convert the pointer back to 
its *ORIGINAL* type (the type it had before it was casted to void*).

Whether you understand the technical problem or not is insignificant. Both the 
standard and C++PL explain you that if you have a void* the only sensible thing 
you can do is casting it back to its original type. If you got a void* from a 
SuperDerived*, you cannot cast it to Derived*. This is wrong: the standard says 
it is undefined behaviour, and you get it. You MUST cast it back to a 
SuperDerived before doing anything else. 

This would work:

static_cast<Derived*> (static_cast<SuperDerived*> (static_cast<void*> (new 
SuperDerived()))).


Also, if you cast it to a Derived* BEFORE casting to void*, you then must cast 
it to Derived* again. For instance:

SuperDerived* -> Derived* -> void* -> SuperDerived*  = WRONG
SuperDerived* -> Derived* -> void* -> Derived* -> SuperDerived*  = CORRECT



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |giovannibajo at libero dot
                   |                            |it


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14827



More information about the Gcc-bugs mailing list