3

I have always avoided the C++ casts (static_cast, const_cast, dynamic_cast [I also avoid RTTI], etc) because I regard them as a waste of typing and I never saw any advantages, so I use C-style casts exclusively.

My question is, if you have an inheritance hierarchy and a pointer to the base type, can you safely cast a base pointer to a derived pointer with a C-style cast (provided that somehow you are absolutely sure the base pointer points to an instance of a derived type) without something happening behind the scenes that will cause seemingly inexplicable failures?

I ask this because I read in one of the comments on another question that using a C-style cast from a base to a derived type will not "adjust the pointer" or something like that. I'll try to find the exact comment again.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249

5 Answers5

7

Using static_cast or dynamic_cast for casting ensures some kind of safety.
static_cast gives you an compile time error if an cast is invalid while,
dynamic_cast throws an exception for References or returns a null pointer in case of invalid cast at run time.

Thus they are better than the c-style cast mainly due the safety they provide.

If you are absolutely sure of the cast being valid even a c-style cast just does the same, but it is better to use the language provided security than rather manage it ourself(since we don't need to).

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Would `static_cast` let me cast a base pointer to a derived pointer? – Seth Carnegie Aug 26 '11 at 05:08
  • @Seth Carnegie: Yes it can, You might want to read [this](http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used) – Alok Save Aug 26 '11 at 05:12
  • @Seth Carnegie: It will work as long as the conversion from the derived pointer to base pointer is valid. – In silico Aug 26 '11 at 05:13
  • 1
    @Seth: gcc may help you track those instances of C-casts within your code using `-Wold-style-cast`. – Matthieu M. Aug 26 '11 at 06:29
1

A dynamic_cast to a pointer (not a reference) gives you a chance to detect an error and handle it; the plain C cast won't. But, if you're absolutely sure about the types, the C-style cast - abominable though it is - should work OK; it was what had to work before there was a C++ standard.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

If your derived class introduces additional members, yes I think things can go wrong if you try to index the pointer or index on the pointer as an array.

Consider the following:

class base
{
public:
    int _data1;

    base () : _data1(0) {}
};

class derived : public base
{
public:
    int _data2;

    derived () : _data2(1) {}
};

int main ()
{
    base *_base_ptr = new derived[10];

    // this isn't going to work correctly, because the compiler will use `sizeof(base)` 
    // to do the pointer offsets, rather than sizeof(derived)...
    int _data = _base_ptr[1]._data1;

    delete[] _base_ptr;

    return _data;
}

Running this snippet in ideone returns 1 rather than the expected 0.

Hope this helps.

Darren Engwirda
  • 6,915
  • 4
  • 26
  • 42
1

The C++ style casts are important in template code. In template code are much less sure of the types of the objects you are casting from or to, because those types have been supplied by the user. C++ style cast will give you compiler errors if you end up doing an unwanted cast (for instance a static cast between unrelated pointer types) but the C style cast will just do the cast anyway.

For instance (trivial example)

template <class T>
T* safe_downcast(Base* ptr)
{
  return static_cast<T*>(ptr);
}

There'd be nothing safe about this function if I used a C style cast.

But I agree, outside of template code I often use C style casts.

john
  • 85,011
  • 4
  • 57
  • 81
0

If you are absolutely sure that the base class pointer actually points to an instance of the derived type, why do you have a base pointer at all? Also: It sounds as if this was a classical case for virtual functions. If you want to avoid virtual calls for some reason (performance, ...), look for CRTP.

I use C++-style casts mainly because they remind me to check whether the cast is absolutely necessary or not by looking ugly. I try to avoid reinterpret_cast and dynamic_cast if at all possible (most of the time it is) and I use static_cast mostly inside CRTP template classes, where it is OK.

arne
  • 4,514
  • 1
  • 28
  • 47
  • I am using virtual functions already and this is not the case for them, and I am sure that the base pointer points to a derived type because I check the type with my own system. – Seth Carnegie Aug 26 '11 at 05:21
  • Why do you implement you own version of run-time type checking system? RTTI exists for a reason. I'm not sure however if vtables (which are often located just in front of the instance) will survive a blind cast. – arne Aug 26 '11 at 05:57