Dynamic_cast compatible?

I was reading about dynamic_cast and then I came across the following statement ( from cplusplus.com ):

Compatibility note: This dynamic_cast type requires a runtime type Information (RTTI) to track dynamic types. Some compilers support this feature as an option that is disabled by default. This must be enabled in order for runtime type checking with dynamic_cast to work with these types.

After the example:

// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;

class Base { virtual void dummy() {} };
class Derived: public Base { int a; };

int main () {
  try {
    Base * pba = new Derived;
    Base * pbb = new Base;
    Derived * pd;

    pd = dynamic_cast<Derived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast.\n";

    pd = dynamic_cast<Derived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast.\n";

  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}

      

What does the author of this dynamic_cast mean? Isn't dynamic_cast only used for polymorphic classes (almost)? And he mentions this RTTI as something that dynamic casting needs to work, does that mean you should use dynamic_cast with care because you don't know if it is fully supported by the compiler and therefore makes it more risky than the other casting to operators who don't need this RTTI?

+3


source to share


3 answers


The compatibility note refers to the immediately preceding paragraph (and example code):

But it dynamic_cast

can also convert (convert from pointer-to-base to pointer-to-born) polymorphic classes (those that have virtual members) if - and only if - the specified object is a valid complete object of the type target.

And it's true: downcasting requires an object of polymorphic type, while RTTI requires traversing the object inheritance tree at runtime.

Another type dynamic_cast

is explained in the paragraph before:



This naturally includes an upcast pointer (conversion from pointer to derivative to pointer to base), just as implicit conversions are allowed.

RTTI is not required here as the underlying database / s are always known statically.

So, you only need to read the surrounding text completely to understand the context of the words you are reading.

I would like to point out, however, that in my experience the compiler with RTTI is disabled by default, mostly unheard of. I'm not saying it doesn't exist - there might be some niche, industry-specific compilers targeting embedded platforms that do this to keep the programmer in bytes in the Makefile. But the compilers that most people use (GCC, Clang, Visual Studio, ICC, Comeau), as far as I know, will package RTTI as standard and leave it on until you ask it to shutdown.

+3


source


The author in the section you mentioned referred to cases where you use dynamic_cast

with polymorphic types: to be a little more precise, when you write something like dynamic_cast<X*>(p)

. In cases like this, you will need the runtime type information to dynamic_cast

be usable at all (see example below).

You can force the compiler to disable the generation of such information about each class using virtual functions using the specified compiler option -fno-rtti

, but this is rarely recommended.

The "other" cases concern use dynamic_cast

for void*

s.



For example, consider the following code:

class A {
public:
  virtual ~A() = default;
};

class B : public A {};

int main()
{
  A *p = new B();
  void *pv = dynamic_cast<void*>(p);
  //B *pb = dynamic_cast<B*>(p);

  delete p;

  return 0;
}

      

If you compile the code with g++ test.cpp -std=c++11 -fno-rtti

, you should be fine. But, if you do the same after the split B *pb = dynamic_cast<B*>(p);

, the compiler will report the following error message for that particular line: error: 'dynamic_cast is not allowed with -fno-rtti. Note that the cast to void*

is performed even when used -fno-rtti

(which was set both manually and by default).

0


source


rtti

is expensive at runtime, and some embedded systems compile with flags disabling it. All this gives you dynamic_cast

and typeid

.

So I interpret

because you don't know if it is fully supported by the compiler

as

because your code may have been compiled with rtti disabled.

-1


source







All Articles