views:

166

answers:

3

Is the type check a mere integer comparison? Or would it make sense to have a GetTypeId virtual function to distinguishing which would make it an integer comparison?

(Just don't want things to be a string comparison on the class names)

EDIT: What I mean is, if I'm often expecting the wrong type, would it make sense to use something like:

struct Token
{
    enum {
        AND,
        OR,
        IF
    };
    virtual std::size_t GetTokenId() = 0;
};

struct AndToken : public Token
{
    std::size_t GetTokenId() { return AND; }
};

And use the GetTokenId member instead of relying on dynamic_cast.

Billy3

+2  A: 

The functionality of the dynamic_cast goes far beyond a simple type check. If it was just a type check, it would be very easy to implement (something like what you have in your original post).

In addition to type checking, dynamic_cast can perform casts to void * and hierarchical cross-casts. These kinds of casts conceptually require some ability to traverse class hierarchy in both directions (up and down). The data structures needed to support such casts are more complicated than a mere scalar type id. The information the dynamic_cast is using is a part of RTTI.

Trying to describe it here would be counterproductive. I used to have a good link that described one possible implementation of RTTI... will try to find it.

AndreyT
So, in my case, where a scalar type id is sufficient, should I use such a scalar?
Billy ONeal
@Billy ONeal: Well, yes... if your really need it. Except I don't understand why you decided to use `size_t` for the return type. `size_t` has nothing to do with all this.
AndreyT
@AndreyT: I use `size_t` as sort of a default unsigned integer type.
Billy ONeal
+1  A: 

In some of the original compilers you are correct they used string comparison.

As a result dynamic_cast<> was very slow (relatively speaking) as the class hierarchy was traversed each step up/down the heirearchy chain required a string compare against the class name.

This lead to a lot of people developing their own casting techniques. This was nearly always ultimately futile as it required each class to be anotated correctly and when things went wrong it was nearly imposable to trace the error.

But that is also acient history.

I am not sure how it is done now but it definately does not involve string comparison. Doing it yourself is also a bad idea (never do work that the compiler is already doing). Any attempt you make will not be as fast or as accurate as the compiler, remember that years of development have gone into makeing the compiler code as quick as possable (and it will always be correct).

Martin York
I suspect that now it's done by comparing vtbl pointers, which are likely linked with superclass (parent) pointers. If you know the class of the object being casted, and the desired class (the template parameter), it's simple enough to get the vtbl pointers from each of those classes and march up the inheritance tree until you come to (or not) a common base class.
Drew Hall
@Drew Hall. Yes that was also a technique (or somthing very similar to your description) was used. But it is a couple of years since I looked at the source of gcc so I don't actually know. But I seem to remember reading a paper on a more effecient mechanism, but it is a long time since I was active in the compiler field.
Martin York
"I am not sure how it is done now but it definately does not involve string comparison". I would not be so sure, today I saw that 'strcmp' was showing in my profiler. After setting a breakpoint in 'strcmp' assembly, I saw that it was called by 'dynamic_cast'... I'm currently sad to use Microsoft Visual Studio 2005 and can hope that things have improved since !
rotoglup
A: 

The compiler cannot divine additional information you may have and stick it in dynamic_cast. If you know certain invariants about your code and you can show that your manual casting mechanism is faster, do it yourself. It doesn't really matter how dynamic_cast is implemented in that case.

MSN
Unfortunately, I don't have oodles of code written yet, but it would be a nontrivial operation to convert from one to the other. There's a large amount of code that goes "Is this token an AND?" ... "Is this token an OR?" ... The actual cast itself isn't really required other than to determine whether I have the correct type.
Billy ONeal