Dynamic cast unexpectedly returns null for a type, but only sometimes and not for other types

StackOverflow https://stackoverflow.com/questions/21147846

  •  28-09-2022
  •  | 
  •  

Question

I have this dynamic cast, which I would expect to always work:

BaseClass *b = new DerivedClass();
DerivedClass *d = dynamic_cast<DerivedClass *>(b);

Well, of course I'm posting this question because it doesn't always work. Here's the situation:

  • BaseClass and DerivedClass are both defined in the same framework.
  • This framework is used in two different applications.
  • For the first application, the dynamic cast works fine (returns b).
  • For the second application, the dynamic cast doesn't work (returns null).
  • For the second application, RTTI seems to be enabled because dynamic casts for other types work.

So what could be causing the dynamic cast for this one type to fail in one application?

Était-ce utile?

La solution

Another thing that can happen with GCC is if some of your code is static-linked and some is dynamic-linked. Or if the same class is defined in two different dynamic libraries.

For example, a type SomeClass in the static linked code will produce a SomeClass typeinfo. And the SomeClass in the dynamic linked code will also produce a SomeClass typeinfo.

What I have seen is that most of the code will point to the dynamic SomeClass typeinfo while all of the code in the static-linked block will point to its internal copy of SomeClass typeinfo.

Since GCC determines types for RTTI and exception handling via typeinfo pointers, this means that as far as it is concerned SomeClass and SomeClass are not the same type.

Now, Microsoft with Windows, probably because they deal with a lot more static linked code and old binary libraries that can't be recompiled, decided to do strcmp name comparisons of types which means that their RTTI and exception handling is a lot slower but works in almost all cases.

Autres conseils

Had this happen to me once. The problem boiled down to the visibility of C++ symbols in the framework. Specifically, the symbols were hidden for some reason.

Now, dynamic_cast requires, in the derived class, to point to some type information for the base class, which can't happen if the symbol is not visible.

Bottom line, setting the visibility for the affected classes like that :

class __attribute__((visibility("default"))) SomeClass
{
    /* ... */
};

solved the issue for us

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top