When Should Static_Cast, Dynamic_Cast, Const_Cast, and Reinterpret_Cast Be Used

When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?

static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary, but it's important to note that the T(something) syntax is equivalent to (T)something and should be avoided (more on that later). A T(something, something_else) is safe, however, and guaranteed to call the constructor.

static_cast can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtual inheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.


const_cast can be used to remove or add const to a variable; no other C++ cast is capable of removing it (not even reinterpret_cast). It is important to note that modifying a formerly const value is only undefined if the original variable is const; if you use it to take the const off a reference to something that wasn't declared with const, it is safe. This can be useful when overloading member functions based on const, for instance. It can also be used to add const to an object, such as to call a member function overload.

const_cast also works similarly on volatile, though that's less common.


dynamic_cast is exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards – you can cast sideways or even up another chain. The dynamic_cast will seek out the desired object and return it if possible. If it can't, it will return nullptr in the case of a pointer, or throw std::bad_cast in the case of a reference.

dynamic_cast has some limitations, though. It doesn't work if there are multiple objects of the same type in the inheritance hierarchy (the so-called 'dreaded diamond') and you aren't using virtual inheritance. It also can only go through public inheritance - it will always fail to travel through protected or private inheritance. This is rarely an issue, however, as such forms of inheritance are rare.


reinterpret_cast is the most dangerous cast, and should be used very sparingly. It turns one type directly into another — such as casting the value from one pointer to another, or storing a pointer in an int, or all sorts of other nasty things. Largely, the only guarantee you get with reinterpret_cast is that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions that reinterpret_cast cannot do, too. It's used primarily for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data, or storing data in the low bits of a pointer to aligned data.


C-style cast and function-style cast are casts using (type)object or type(object), respectively, and are functionally equivalent. They are defined as the first of the following which succeeds:

  • const_cast
  • static_cast (though ignoring access restrictions)
  • static_cast (see above), then const_cast
  • reinterpret_cast
  • reinterpret_cast, then const_cast

It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a reinterpret_cast, and the latter should be preferred when explicit casting is needed, unless you are sure static_cast will succeed or reinterpret_cast will fail. Even then, consider the longer, more explicit option.

C-style casts also ignore access control when performing a static_cast, which means that they have the ability to perform an operation that no other cast can. This is mostly a kludge, though, and in my mind is just another reason to avoid C-style casts.

Which cast to use; static_cast or reinterpret_cast?

static_cast provided that you know (by design of your program) that the thing pointed to really is an int.

static_cast is designed to reverse any implicit conversion. You converted to void* implicitly, therefore you can (and should) convert back with static_cast if you know that you really are just reversing an earlier conversion.

With that assumption, nothing is being reinterpreted - void is an incomplete type, meaning that it has no values, so at no point are you interpreting either a stored int value "as void" or a stored "void value" as int. void* is just an ugly way of saying, "I don't know the type, but I'm going to pass the pointer on to someone else who does".

reinterpret_cast if you've omitted details that mean you might actually be reading memory using a type other than the type is was written with, and be aware that your code will have limited portability.

By the way, there are not very many good reasons for using a void* pointer in this way in C++. C-style callback interfaces can often be replaced with either a template function (for anything that resembles the standard function qsort) or a virtual interface (for anything that resembles a registered listener). If your C++ code is using some C API then of course you don't have much choice.

What is the difference between static_cast and reinterpret_cast? [duplicate]

A static_cast is a cast from one type to another that (intuitively) is a cast that could under some circumstance succeed and be meaningful in the absence of a dangerous cast. For example, you can static_cast a void* to an int*, since the void* might actually point at an int*, or an int to a char, since such a conversion is meaningful. However, you cannot static_cast an int* to a double*, since this conversion only makes sense if the int* has somehow been mangled to point at a double*.

A reinterpret_cast is a cast that represents an unsafe conversion that might reinterpret the bits of one value as the bits of another value. For example, casting an int* to a double* is legal with a reinterpret_cast, though the result is unspecified. Similarly, casting an int to a void* is perfectly legal with reinterpret_cast, though it's unsafe.

Neither static_cast nor reinterpret_cast can remove const from something. You cannot cast a const int* to an int* using either of these casts. For this, you would use a const_cast.

A C-style cast of the form (T) is defined as trying to do a static_cast if possible, falling back on a reinterpret_cast if that doesn't work. It also will apply a const_cast if it absolutely must.

In general, you should always prefer static_cast for casting that should be safe. If you accidentally try doing a cast that isn't well-defined, then the compiler will report an error. Only use reinterpret_cast if what you're doing really is changing the interpretation of some bits in the machine, and only use a C-style cast if you're willing to risk doing a reinterpret_cast. In your case, you should use the static_cast, since the downcast from the void* is well-defined in some circumstances.

const_cast vs static_cast

Don't use either. Initialize a const reference that refers to the object:

T x;
const T& xref(x);

x.f(); // calls non-const overload
xref.f(); // calls const overload

Or, use an implicit_cast function template, like the one provided in Boost:

T x;

x.f(); // calls non-const overload
implicit_cast<const T&>(x).f(); // calls const overload

Given the choice between static_cast and const_cast, static_cast is definitely preferable: const_cast should only be used to cast away constness because it is the only cast that can do so, and casting away constness is inherently dangerous. Modifying an object via a pointer or reference obtained by casting away constness may result in undefined behavior.

what is the necessity of c++ static cast

The main reason to use a static_cast<> over a dynamic_cast<> is performance. With the dynamic_cast<>, you get code that actually checks the dynamic type of the object, adjusting the pointer as appropriate; a static_cast<> always compiles to a single addition instruction at most. And since the dynamic type check may get expensive, static_cast<> can be orders of magnitude faster than the corresponding dynamic_cast<>.

Apart from this performance consideration, static_cast<> is not strictly needed, you can do anything it does with dynamic_cast<> or C-style casts.

When must/should dynamic_cast be used over static_cast?

In general, you should use dynamic_cast when converting within a
hierarchy, regardless. One possible exception is when converting from a
derived class to a base (pointers or references, of course). Otherwise,
about the only time you'd use static_cast within a hierarchy is when
the profilers says you must.

static_cast is more often used when converting to or from a void*,
or to ensure the correct type of a null pointer constant, or for
conversions which don't involve pointers or references (e.g.
static_cast<double>( someInt )).

const_cast vs reinterpret_cast

reinterpret_cast changes the interpretation of the data within the object. const_cast adds or removes the const qualifier. Data representation and constness are orthogonal. So it makes sense to have different cast keywords.

So if I add constness using reinterpret_cast and if you reinterpret_cast the result back to the original type, it should result back to the original type and should not be UB, but that violates the fact that one should only use const_cast to remove the constness

That wouldn't even compile:

int * n = new int;
const * const_added = reinterpret_cast<const int *>(n);
int * original_type = reinterpret_cast<int*>(const_added);
// error: reinterpret_cast from type ‘const int*’ to type ‘int*’ casts away qualifiers

Regular cast vs. static_cast vs. dynamic_cast [duplicate]

static_cast

static_cast is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. static_cast performs no runtime checks. This should be used if you know that you refer to an object of a specific type, and thus a check would be unnecessary. Example:

void func(void *data) {
// Conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}

int main() {
MyClass c;
start_thread(&func, &c) // func(&c) will be called
.join();
}

In this example, you know that you passed a MyClass object, and thus there isn't any need for a runtime check to ensure this.

dynamic_cast

dynamic_cast is useful when you don't know what the dynamic type of the object is. It returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a bad_cast exception is thrown in that case).

if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
...
}

You can not use dynamic_cast for downcast (casting to a derived class) if the argument type is not polymorphic. For example, the following code is not valid, because Base doesn't contain any virtual function:

struct Base { };
struct Derived : Base { };
int main() {
Derived d; Base *b = &d;
dynamic_cast<Derived*>(b); // Invalid
}

An "up-cast" (cast to the base class) is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion (assuming the base class is accessible, i.e. it's a public inheritance).

Regular Cast

These casts are also called C-style cast. A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works, without ever considering dynamic_cast. Needless to say, this is much more powerful as it combines all of const_cast, static_cast and reinterpret_cast, but it's also unsafe, because it does not use dynamic_cast.

In addition, C-style casts not only allow you to do this, but they also allow you to safely cast to a private base-class, while the "equivalent" static_cast sequence would give you a compile-time error for that.

Some people prefer C-style casts because of their brevity. I use them for numeric casts only, and use the appropriate C++ casts when user defined types are involved, as they provide stricter checking.



Related Topics



Leave a reply



Submit