Announcement

Collapse
No announcement yet.

[Compiler]Enable Run-Time Type Information

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [Compiler]Enable Run-Time Type Information

    Hey guys,

    Today I ran into problems using dynamic_cast with a custom class - API class - for which I got the following error:
    Code:
    Severity Code Descript'dynamic_cast' used on polymorphic type 'Condition' with /GR-; unpredictable behavior may result
    Which makes perfect sense. Question is, how can I enable it?
    I should see something like Click image for larger version

Name:	CodeGeneration.PNG
Views:	1
Size:	47.8 KB
ID:	1166638 that on project proprieties, but I don't, for some reason, I never do in UE4 projects.

    Any help?

    #2
    UE4 disables C++ RTTI for a number of reasons. However, the main one is that UE4 builds its own RTTI and using built in RTTI would be quite wasteful. Furthermore, it could cause unknown errors as I doubt it has been tried.

    Instead of doing a dynamic cast, just use a plain C-style cast or Epic's own Cast template function.

    Comment


      #3
      Originally posted by zacharymwade View Post
      UE4 disables C++ RTTI for a number of reasons. However, the main one is that UE4 builds its own RTTI and using built in RTTI would be quite wasteful. Furthermore, it could cause unknown errors as I doubt it has been tried.

      Instead of doing a dynamic cast, just use a plain C-style cast or Epic's own Cast template function.
      Problem is this isn't a UClass* derived class, its a simple C++ class

      Comment


        #4
        Quickest way would be to make it a UCLASS and inherit from UObject IMO.

        Comment


          #5
          Originally posted by TheJamsh View Post
          Quickest way would be to make it a UCLASS and inherit from UObject IMO.
          It's not always a good idea to make everything a UObject though. The extra functionality that UObject provides comes with extra overhead, and this results in UObject not being a good base class for small, short-lived objects for example.

          Comment


            #6
            Presumably there is a type-hierarchy being used here, else dynamic_cast wouldn't work, so you'll need to provide a type property to identify the class type in place of RTTI.

            Comment


              #7
              Yep, you'll either need to store some type information yourself, or probably better, just redesign so that it's not necessary.

              Generally use of dynamic_cast can be replaced by use of polymorphism (virtual functions). Your code will likely end up much cleaner if you don't need to check at runtime if an object is of a particular derived type, but just invoke a virtual function on it instead.

              Comment


                #8
                Sorry for the late reply, here's how the code is at the moment - because it has one pure virtual function:

                Code:
                class Game_API Base
                {
                public:
                
                ....
                
                	virtual bool TestImpl(.....) = 0;
                then I have several classes which implement Base,e.g.
                Code:
                class Game_API A : public Base
                class Game_API B : public Base
                class Game_API C : public Base
                Finally, inside class A I have a method ,e.g.

                Code:
                void A::JustAMethod(Base* obj)
                {
                ....
                And now I want to see if obj is an instance of A,B or C - it cannot be of instance Base since it has pure virtual functions. And this is when I get the error, when I try to castobj to A.
                Last edited by GuilhermeB; 11-18-2015, 07:22 AM.

                Comment


                  #9
                  Without knowing what your code is trying to do or why, a simple and easy solution to this would be to create an enum with a value mapping to each of your class types. Then, add a virtual function to your base class that's something like GetClassType. Then, in each of the child classes, have them implement that function and return their corresponding enum.

                  You could also accomplish this without the enum by using individual functions i.e IsClassA(), IsClassB(), etc. This can make your code messy very quickly, but it's also more flexible. For instance, you could support ClassC which is a child of ClassB which is a child of ClassA, and you would be able to call IsClassA(), IsClassB(), and IsClassC() and they would all return true.

                  Comment


                    #10
                    Originally posted by ddbrown30 View Post
                    Without knowing what your code is trying to do or why, a simple and easy solution to this would be to create an enum with a value mapping to each of your class types. Then, add a virtual function to your base class that's something like GetClassType. Then, in each of the child classes, have them implement that function and return their corresponding enum.

                    You could also accomplish this without the enum by using individual functions i.e IsClassA(), IsClassB(), etc. This can make your code messy very quickly, but it's also more flexible. For instance, you could support ClassC which is a child of ClassB which is a child of ClassA, and you would be able to call IsClassA(), IsClassB(), and IsClassC() and they would all return true.
                    Hello ddbrown!

                    Yes I had considered the first option - the second one, for practical and good-standard programming reasons, I haven't considered it - but, its not that practical nor makes sense having to resort to such options. I mean, this is exactly what casting is for, I can't quite understand why it isn't working when I have polyphormism (at least one pure virtual method is in the base class).

                    Comment


                      #11
                      If it's just an isolated situation then the first option will work, but it's not ideal, it isn't scalable at all.

                      With polymorphism though, the whole idea is that you don't need to ask what type of object you're dealing with. You just invoke a virtual function, and the various implementations will do whatever they need to do. In some cases, for some classes that may be nothing at all. You haven't said what you're trying to achieve on a higher level though, so it's hard to say how you should go about it.

                      Comment


                        #12
                        Originally posted by GuilhermeB View Post
                        Hello ddbrown!

                        Yes I had considered the first option - the second one, for practical and good-standard programming reasons, I haven't considered it - but, its not that practical nor makes sense having to resort to such options. I mean, this is exactly what casting is for, I can't quite understand why it isn't working when I have polyphormism (at least one pure virtual method is in the base class).
                        Dynamic casting is slooooooooow. That's why pretty much every professional engine implements their own version. Vtable lookups also have a cost, but the hit is small and usually only matters in places where performance is critical.

                        The common pattern for implementing custom RTTI is how Unreal does it. They have macros for writing a bunch of the boilerplate code, with functions that are comparing class IDs that are generated based on the class name. You can take a look at cast.h if you'd like to see it in action.

                        Comment


                          #13
                          Originally posted by ddbrown30 View Post
                          Dynamic casting is slooooooooow. That's why pretty much every professional engine implements their own version. Vtable lookups also have a cost, but the hit is small and usually only matters in places where performance is critical.

                          The common pattern for implementing custom RTTI is how Unreal does it. They have macros for writing a bunch of the boilerplate code, with functions that are comparing class IDs that are generated based on the class name. You can take a look at cast.h if you'd like to see it in action.
                          Well I know its slow, but tbh the code will be executed only once - when the game loads - and only a few times over, so its not that problematic I guess, although better performance solutions would be better

                          As for the custom RTII...way beyond my knowledge lol

                          Comment

                          Working...
                          X