Am I right in assuming that C-style casts (which are discouraged) are nothing but reinterpret_casts? Using the latter is visually striking and easy to search when looking for nasty casts, and hence it's recommended over C-style casts?
If casting away const using const_cast and writing to a originally const object is undefined, what is the purpose of const_cast?
Note: I know that Bjarne rightly condemns casting operations that they are unsafe and even goes to the extent of stating "An ugly operation should have an ugly syntactic form." and hence the verbosity of casting operators in C++. So I'll try to minimize their usage. Promise. :)
Const casts are only available in C++. Const casts are used to strip the const-ness or volatile-ness from a variable.
static_cast only allows conversions like int to float or base class pointer to derived class pointer. reinterpret_cast allows anything, that's usually a dangerous thing and normally reinterpret_cast is rarely used, tipically to convert pointers to/from integers or to allow some kind of low level memory manipulation.
C-style casts can be used to convert any type into any other type, potentially with unsafe results (such as casting an integer into a pointer type). (<type>)<value> This example casts an int to a double for the purpose of avoiding truncation due to integer division: double result = (double)4/5; Popular pages.
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.
No. A C cast can do the equivalent of a const_cast
, a static_cast
, a reinterpret_cast
, or a combination thereof. In case that wasn't quite enough, it can also do at least one minor trick that no combination of the newer casts can do at all!
You can use const_cast
with defined results if the original variable is defined without const
, but all you have is a const
pointer or reference to that object. OTOH, if you think you have a good reason to use a const_cast
, chances are that you should really look up mutable
instead.
Edit: I suppose I should have said it right off, but a C-style cast can convert to an an inaccessible base class. For example, consider something like:
[Edit: I'm updating the code to something that'll compile and (usually) demonstrate problem. ]
#include <iostream>
class base1 {
public:
virtual void print() { std::cout << "base 1\n"; }
};
class base2 {
public:
virtual void print() { std::cout << "base 2\n"; }
};
class derived : base1, base2 {}; // note: private inheritance
int main() {
derived *d = new derived;
base1 *b1 = (base1 *)d; // allowed
b1->print(); // prints "base 1"
base2 *b2 = (base2 *)d; // also allowed
b2->print(); // prints "base 2"
// base1 *bb1 = static_cast<base *>(d); // not allowed: base is inaccessible
// Using `reinterpret_cast` allows the code to compile.
// Unfortunately the result is different, and normally won't work.
base1 *bb2 = reinterpret_cast<base1 *>(d);
bb2->print(); // may cause nasal demons.
base2 *bb3 = reinterpret_cast<base2 *>(d);
bb3->print(); // likewise
return 0;
}
The code using the reinterpret_cast
s will compile -- but attempting to use the result (of at lest one of the two) will cause a major problem. The reinterpret_cast
takes the base address of the derived object and attempts to treat it as if it was the specified type of base object -- and since (at most) one base object can actually exist at that address, trying to treat it as the other can/will cause major problems. Edit: In this case, the classes are essentially identical except for what they print, so although anything could happen, with most compilers, both of the last two will print out "base 1". The reinterpret_cast takes whatever happens to be at that address and tries to use it as the specified type. In this case, I've (tried to) make that do something harmless but visible. In real code, the result probably won't be so pretty.
The C-style cast will work like a static_cast would if the code had used public inheritance instead of private -- i.e. it's aware of where in the derived class each base class object "lives", and adjusts the result, so each resulting pointer will work because it's been adjusted to point at the right place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With