6

I am seeing a strange failure where the dynamic_cast is returning NULL on clang compiler. But the same code is working with gcc environment.

Could you please point me what might be the root cause? What might the difference between the dynamic_cast on llvm and gcc.

I am using the default behavior of both the compiler where i think the RTTI is enable by default.

template<typename T> T* 
find_msg_of_type(
    MsgList *list
) {
    T* msg = NULL;

    if (list) {
        for (std::vector<MsgList*>::iterator it = list->element.begin();
                                                        it != list->element.end();
                                                        it++) {// MsgList can be list of objects build with GSoap.
            if (typeid(*(*it)) == typeid(T)) {
                msg = dynamic_cast<T*>(*it); // Failing on clang but this same code is working with gcc compiler.
                break;
            }
        }
    }

    return msg;
}

One more observation: With gcc

if (typeid(*(*it)) == typeid(T))

is working perfectly as expected but with clang

if (typeid(*(*it)) == typeid(T))

comparison is showing different behavior.. not sure exactly why this differs.

Thanks

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • 7
    That could be many things. Are you sure the type is the same in both compilers? And does have virtual methods table in both compilers? And is RTTI enabled in both compilers? Try reducing the problem to a small example and post it along with compiler commands used. – Jan Hudec Jan 02 '13 at 09:09
  • Don't write it in comments, EDIT THE QUESTION! Additional details should always be added to the question body. That's why they are editable! – Jan Hudec Jan 02 '13 at 15:26
  • Try printing the `typeid(**it)` and `typeid(T)`—and `typeid(*it)` and `typeid(T*)`—in debug messages. Also move the `dynamic_cast` out of the condition and check it for returning `NULL`—the dynamic cast does the typeid comparison internally, but it also accepts descendant instances. – Jan Hudec Jan 03 '13 at 06:58
  • I had printed both typeid(*(*it)).name() and typeid(T).name(), both are same and even i did check after moving the dynamic_cast out of the condition. I show clearly dynamic_cast is returning NULL only. Not sure exactly why! One more point for your information, the MsgList will hold msg which will be build with GSoap at run time. I am not understanding how it can make differ as i am seeing the same code is working with gcc perfectly. – Abhrajyoti Kirtania Jan 03 '13 at 08:46
  • What versions of each compiler are you using? What platform and platform version are you on? When you say "comparison is showing different behavior," what is that different behavior? – bames53 Jan 03 '13 at 16:21
  • Xcode 4.5. Platform: Mac OSX Mountain Lion;Run time with clang environment "if (typeid(*(*it)) == typeid(T))" instruction always showing false value but if i print this as typeid(*(*it)).name() and typeid(T).name(); it is showing the same class name. – Abhrajyoti Kirtania Jan 05 '13 at 19:09
  • I just encountered the same issue. I have `rtti` enabled. – dcow Feb 25 '16 at 02:51

1 Answers1

0

For code like this, a Good Idea is to statically ensure that the class T is derived from MsgList. Using boost, this can be done thusly:

BOOST_STATIC_ASSERT((boost::is_base_and_derived::value));

emilk
  • 324
  • 2
  • 5