CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jun 2000
    Location
    austin
    Posts
    101

    whats up with dynamic_cast, static_cast, and reinterpret_cast?

    i don't understand what these do...

    dynamic_cast<>
    static_cast<>
    reinterpret_cast<>



    why not just use normal type casting? when i use any of those 3 things, i have compilation problems anyways. thanks for the help. oh yeah, can someone explain to me what the #pragma directive does? thanks!


    -christopher bottaro
    cjb@cs.utexas.edu
    cjb9@mail.utexas.edu
    christopher.bottaro@broadwing.com

  2. #2
    Join Date
    Nov 1999
    Location
    Dresden / Germoney
    Posts
    1,402

    Re: whats up with dynamic_cast, static_cast, and reinterpret_cast?

    Hi,

    reason is: the "normal" cast ( (TYPE) x ) covers four different intentions of casting (that actually do three completely different things on Assembler level). The "C++ style" casts were introduced so the programmer can state what he really wants.

    There are the following types of a cast:

    * type conversion, like "int" to "float": the _contents_ of the variable will be read and converted (according to some type specific rules)

    * casting up in class hierarchy (i.e. cast a dereived class pointer to a base class pointer). On ASM level, usually an offset needs to be added or subtracted from the pointer to the class

    * casting down in class hierarchy, i.e. from base to dereived class. This is only safe with run-time information about the class hierarchy, and the "true class" of an object. Again, adding or subtractng an offset from class pointer is necessary

    * "hard" cast - treat the data as if it were of different type ("assume the bits at this address are integers"). "Nothing" happens at assembly level (since in machine code, all pointers are void *)

    * removing "const" modifiers - again, nothng really happens at assembly (it's only to tell the compiler "I know I break const correctness rules here, please don't complain")


    Note that only "hard cast" and "conversion" were possible in classic C, and they could easily be separated (if it's a pointer, it's a "hard" cast).
    However, in C++ the ((CFoo *) ptr) can mean a lot of different things, depending on the type of ptr.
    Errors introduced by wrongly using the C-style cast operator are notoriously hard to track down.

    Now, the real answer:

    static_cast does a "safe" type cast, based on the type information available at compile time. static_cast allows type conversion, and casting up in class hierarchy

    dynamic_cast does a "safe" type cast, using run time type information, to cast down in class hierarchy. (i.e. it's checked at runtime if the CBase * actually points to a CDereived). For dynamic_cast to work, you must enable RTTI (Run time Type Information) in the C++ compiler settings.

    reinterpret_cast does a hard cast - "assume the bits.."

    const_cast does the const modifier removal.

    -------------

    Syntax is:

    xxx_cast<destination-type>(expression)
    but this of course works only in C++.
    -------------

    #pragma directives are compiler-specific, they are clearly not part of ANSI or whatever standard. More exactly, the "#pragma" itself is standard, but what follows is compiler-dependent. There are various #pragma directives in MSVC++, from supressing certain warnings to specifying which .lib's the module should be linked to.

    Helped?
    Peter


    P.S. "conversion" cast is not an official or common term; I just used it here since it best describes the action taken


    [edited to fix minor typos and a major error]
    Last edited by peterchen; November 23rd, 2002 at 04:03 PM.

  3. #3
    Join Date
    Aug 2002
    Posts
    78

    So is reinterpret_cast any different from "old" casts?

    Eight web pages, and two forum articles still don't really answer the question, although this explanation seems to do it, thanks!

    For use with qsort's callback function:
    Code:
    int myCompare(void *e1, void *e2)
    {
    
         MyClass *c1 = *(MyClass **) e1; // Compare is ptr to ptr to object.
    
         MyClass *c2 = *(MyClass **) e2;
    
    
         return (some comparison code);
    }

    So would one use reinterpret_cast here? (Pointers are guaranteed to be to the class that is being qsorted in the array, not any derived or parent version, i.e. it's an array of MyClasses, not of any parent or child of them.)

    And: given it's void, wouldn't the old-style cast be acceptable?

  4. #4
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    Check this forum thread for answers:

    http://www.codeguru.com/forum/showth...einterpretcast

    and yes. reinterpret_cast is exactly the same as the old C cast.
    Last edited by proxima centaur; November 20th, 2002 at 04:06 PM.
    Martin Breton
    3D vision software developer and system integrator.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: So is reinterpret_cast any different from "old" casts?

    Originally posted by Gorgor
    For use with qsort's callback function:So would one use reinterpret_cast here? (Pointers are guaranteed to be to the class that is being qsorted in the array, not any derived or parent version, i.e. it's an array of MyClasses, not of any parent or child of them.)
    Oh no!

    So you are calling qsort() on an array of MyClasses or pointers to them? If it is an array of MyClasses, qsort() can only be guaranteed to work if MyClasses is a POD (Plain-Old-Data) class (i.e. it is a struct or class consisting of int's doubles, chars, pointers, arrays of these things, etc.). If it contains non-POD items like std::string, CList, vector, etc. or non-trivial constructors, destructors, etc., qsort is not guaranteed to work. Use std::sort to sort objects correctly, not qsort. Not only that, the ugly pointer code you're doing now with qsort would be a thing of the past.

    There was a long thread on this in the non-Visual C++ group -- qsort is not guaranteed to sort an array of non-POD objects correctly. As a matter of fact, it totally messed up an array of objects when tested on several compilers, while std::sort worked perfectly.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    Re: Re: whats up with dynamic_cast, static_cast, and reinterpret_cast?

    Originally posted by peterchen
    Hi,

    * casting up in class hierarchy (i.e. cast a dereived class pointer to a base class pointer). Typically, an offset needs to be added or subtracted from the pointer to the class

    * casting down in class hierarchy, i.e. from base to dereived class. This is only safe with run-time information about the class hierarchy. Again, adding or subtractng an offset from class pointer is necessary
    Can you give me some more information about this offset.
    thanks

  7. #7
    Join Date
    Nov 1999
    Location
    Dresden / Germoney
    Posts
    1,402
    Gorgor: Thanks! It's always nice to hear a post has been helpful, especially if it's 2 years old....

    souldog:
    all this is very compiler-dependent, but there's a "normal" implementation, at least for single-inheritance-hierarchies.

    imagine two classes

    class CAlpha
    {
    public: int a;
    };

    class CBeta : public CAlpha
    {
    public: int b;
    };

    class CGamma : public CBeta
    {
    public: int c;
    };


    (Only data members matter for the discussion, as member functions don't require per-instance data)

    So an instance of of CGamma would be layed out like this (the base address is meaningless, just as an example):

    Code:
    [0x100] CGamma * ---> CGamma.c
    [0x104] CBeta * --->   CBeta.b
    [0x108] CAlpha * --->   CAlpha.a
    so if you cast from CAlpha to CBeta, the compiler will subtract 4 from the pointer.

    You can reverse the stack (only accesisng the class members gets weirder on ASM level).

    If you have multiple inheritance, things get much more tricky, but in general, it's possible in a similar way.

  8. #8
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863
    Thanks Peter, that was helpful

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured