C++ style casts are checked by the compiler. C style casts aren't and can fail at runtime.
Also, C++ style casts can be searched for easily, whereas it's really hard to search for C style casts.
Another big benefit is that the 4 different C++ style casts express the intent of the programmer more clearly.
When writing C++ I'd pretty much always use the C++ ones over the the C style.
Answer from Glen on Stack OverflowC++ style casts are checked by the compiler. C style casts aren't and can fail at runtime.
Also, C++ style casts can be searched for easily, whereas it's really hard to search for C style casts.
Another big benefit is that the 4 different C++ style casts express the intent of the programmer more clearly.
When writing C++ I'd pretty much always use the C++ ones over the the C style.
In short:
static_cast<>()gives you a compile time checking ability, C-Style cast doesn't.static_cast<>()is more readable and can be spotted easily anywhere inside a C++ source code, C_Style cast is'nt.- Intentions are conveyed much better using C++ casts.
More Explanation:
The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a pointer to a 4-byte type, pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
You can also check this page on more explanation on C++ casts : Click Here
Why use static_cast over C style cast for primitive data types?
type casting - c style casts or c++ style casts - Software Engineering Stack Exchange
static_cast and ( ) - C++ Forum
c++ - Why use static_cast (x) instead of (T)x or T(x)? - Stack Overflow
Videos
C style cast are faster to write and I prefer them when dealing with basic types. I find it annoying to write static_cast<double>(my_int) just so I can cast something to double for whatever the reason.
Are there any benefits of using statics_cast over C style cast for basic types?
C++ style casts are checked by the compiler. C style casts aren't and can fail at runtime.
Also, C++ style casts can be searched for easily, whereas it's really hard to search for C style casts.
Another big benefit is that the 4 different C++ style casts express the intent of the programmer more clearly.
When writing C++ I'd pretty much always use the C++ ones over the the C style.
Answer from Glen on Stack OverflowFirst, understand that those lines are not equivalent.
int* anInt = (int*)aFloat; // is equivalent to
int* anInt = reinterpret_cast<int*>(aFloat);
What is happening here is that the programmer is asking the compiler to do whatever it can to make the cast.
The difference is important because using static_cast will only ask for a base type that is "safe" to convert to, where reinterpret_cast will convert to anything, possibly by just mapping the wanted memory layout over the memory of the given object.
So, as the "filter" is not the same, using a specific cast is more clear and safe than using the C cast. If you rely on the compiler (or runtime implementation if you use dynamic_cast) to tell you where you did something wrong, by avoid using C cast and reinterepret_cast.
Now that this is more clear, there is another thing: static_cast, reinterpret_cast, const_cast and dynamic_cast are easier to search for.
And the ultimate point: they are ugly. That's wanted. Potentially buggy code, code smells, obvious "tricks" that might generate bugs, are easier to track when it's associated with ugly look. Bad code should be ugly.
That's "by design". And that allows the developer to know where he could have done things better (by totally avoiding casts, if not really needed) and where it's fine but it's "documented" in the code by "marking" it as ugly.
A secondary reason for introducing the new-style cast was that C-style casts are very hard to spot in a program. For example, you can't conveniently search for casts using an ordinary editor or word processor. This near-invisibility of C-style casts is especially unfortunate because they are so potentially damaging. An ugly operation should have an ugly syntactic form. That observation was part of the reason for choosing the syntax for the new-style casts. A further reason was for the new-style casts to match the template notation, so that programmers can write their own casts, especially run-time checked casts.
Maybe, because static_cast is so ugly and so relatively hard to type, you're more likely to think twice before using one? That would be good, because casts really are mostly avoidable in modern C++.
Source: Bjarne Stroustrup (C++ creator)
C++ casts are more restrictive (so express your intent better and make code review easier, etc.). They're also much easier to search for, if you ever need to.
The main reason is that classic C casts make no distinction between what we call static_cast<>(), reinterpret_cast<>(), const_cast<>(), and dynamic_cast<>(). These four things are completely different.
A static_cast<>() is usually safe. There is a valid conversion in the language, or an appropriate constructor that makes it possible. The only time it's a bit risky is when you cast down to an inherited class; you must make sure that the object is actually the descendant that you claim it is, by means external to the language (like a flag in the object). A dynamic_cast<>() is safe as long as the result is checked (pointer) or a possible exception is taken into account (reference).
A reinterpret_cast<>() (or a const_cast<>()) on the other hand is always dangerous. You tell the compiler: "trust me: I know this doesn't look like a foo (this looks as if it isn't mutable), but it is".
The first problem is that it's almost impossible to tell which one will occur in a C-style cast without looking at large and disperse pieces of code and knowing all the rules.
Let's assume these:
class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
Now, these two are compiled the same way:
CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked
pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
// Safe; as long as we checked
// but harder to read
However, let's see this almost identical code:
CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert
pOther = (CMyOtherStuff*)(pSomething); // No compiler error.
// Same as reinterpret_cast<>
// and it's wrong!!!
As you can see, there is no easy way to distinguish between the two situations without knowing a lot about all the classes involved.
The second problem is that the C-style casts are too hard to locate. In complex expressions it can be very hard to see C-style casts. It is virtually impossible to write an automated tool that needs to locate C-style casts (for example a search tool) without a full blown C++ compiler front-end. On the other hand, it's easy to search for "static_cast<" or "reinterpret_cast<".
pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
// No compiler error.
// but the presence of a reinterpret_cast<> is
// like a Siren with Red Flashing Lights in your code.
// The mere typing of it should cause you to feel VERY uncomfortable.
That means that, not only are C-style casts more dangerous, but it's a lot harder to find them all to make sure that they are correct.
One pragmatic tip: you can search easily for the static_cast keyword in your source code if you plan to tidy up the project.
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.
Static cast
The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
Reinterpret cast
To force the pointer conversion, in the same way as the C-style cast does in the background, the reinterpret cast would be used instead.
int *r = reinterpret_cast<int*>(&c); // forced conversion
This cast handles conversions between certain unrelated types, such as from one pointer type to another incompatible pointer type. It will simply perform a binary copy of the data without altering the underlying bit pattern. Note that the result of such a low-level operation is system-specific and therefore not portable. It should be used with caution if it cannot be avoided altogether.
Dynamic cast
This one is only used to convert object pointers and object references into other pointer or reference types in the inheritance hierarchy. It is the only cast that makes sure that the object pointed to can be converted, by performing a run-time check that the pointer refers to a complete object of the destination type. For this run-time check to be possible the object must be polymorphic. That is, the class must define or inherit at least one virtual function. This is because the compiler will only generate the needed run-time type information for such objects.
Dynamic cast examples
In the example below, a MyChild pointer is converted into a MyBase pointer using a dynamic cast. This derived-to-base conversion succeeds, because the Child object includes a complete Base object.
class MyBase
{
public:
virtual void test() {}
};
class MyChild : public MyBase {};
int main()
{
MyChild *child = new MyChild();
MyBase *base = dynamic_cast<MyBase*>(child); // ok
}
The next example attempts to convert a MyBase pointer to a MyChild pointer. Since the Base object does not contain a complete Child object this pointer conversion will fail. To indicate this, the dynamic cast returns a null pointer. This gives a convenient way to check whether or not a conversion has succeeded during run-time.
MyBase *base = new MyBase();
MyChild *child = dynamic_cast<MyChild*>(base);
if (child == 0)
std::cout << "Null pointer returned";
If a reference is converted instead of a pointer, the dynamic cast will then fail by throwing a bad_cast exception. This needs to be handled using a try-catch statement.
#include <exception>
// โฆ
try
{
MyChild &child = dynamic_cast<MyChild&>(*base);
}
catch(std::bad_cast &e)
{
std::cout << e.what(); // bad dynamic_cast
}
Dynamic or static cast
The advantage of using a dynamic cast is that it allows the programmer to check whether or not a conversion has succeeded during run-time. The disadvantage is that there is a performance overhead associated with doing this check. For this reason using a static cast would have been preferable in the first example, because a derived-to-base conversion will never fail.
MyBase *base = static_cast<MyBase*>(child); // ok
However, in the second example the conversion may lead to run-time error. The error will happen if the MyBase object contains a MyBase instance but not if it contains a MyChild instance. In some situations this may not be known until run-time. When this is the case dynamic cast is a better choice than static cast.
// Succeeds for a MyChild object
MyChild *child = dynamic_cast<MyChild*>(base);
If the base-to-derived conversion had been performed using a static cast instead of a dynamic cast the conversion would not have failed. It would have returned a pointer that referred to an incomplete object. Dereferencing such a pointer can lead to run-time errors.
// Allowed, but invalid
MyChild *child = static_cast<MyChild*>(base);
// Incomplete MyChild object dereferenced
(*child);
Const cast
This one is primarily used to add or remove the const modifier of a variable.
const int myConst = 5;
int *nonConst = const_cast<int*>(&myConst); // removes const
Although const cast allows the value of a constant to be changed, doing so is still invalid code that may cause a run-time error. This could occur for example if the constant was located in a section of read-only memory.
*nonConst = 10; // potential run-time error
const cast is instead used mainly when there is a function that takes a non-constant pointer argument, even though it does not modify the pointee.
void print(int *p)
{
std::cout << *p;
}
The function can then be passed a constant variable by using a const cast.
print(&myConst); // error: cannot convert
// const int* to int*
print(nonConst); // allowed
Source and More Explanations