I have been reading a lot about C++ casting and I am starting to get confused because I have always used C style casting.
I have read that C style casting should be avoided in C++ and that reinterpret_cast is very very dangerous and should not be used whenever there is an alternative. On the contrary to not using reinterpret_cast, I have seen it used many times on MSDN in their sample code. This leads me to ask my first question, when is it ok to use reinterpret_cast?
For example:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_CREATE:
{
LPCREATESTRUCT lpCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
return 0;
}
}
...
}
If that is not ok, then how would I cast the LPARAM value to a pointer using only static, dynamic, and/or const casting?
Also: If reinterpret_cast is not portable, how would I rewrite it to be portable (for good practice)
Using reinterpret_cast is acceptable if you know that the pointer was originally of the destination type. Any other use is taking advantage of implementation-dependent behavior, although in many cases this is necessary and useful, such as casting a pointer to a structure into a pointer to bytes so that it can be serialized.
It is considered dangerous because it does no checking, either at compile-time or at runtime. If you make a mistake, it can and will crash and burn horribly, and be difficult to debug. You are essentially telling the compiler "I know better than you what this actually is, so just compile the code and let me worry about the consequences."
The reason you see it on MSDN is because the Win32 API is a C API, but people insist on giving examples in C++.
Reinterpret cast is fine when you're writing code that interfaces with other libraries. It should be avoided within your own app.
This is an example of programming the Windows Platform SDK, a C API, with C++. The window procedure only has the WPARAM and LPARAM parameters and if you need to pass a pointer to a structure through a window message, it has to be cast. This is a perfectly acceptable use of reinterpret_cast<> in my opinion. You cannot avoid a cast because the SDK you are writing to, which is not your code, was not designed for C++, much less type-safety, and needs the casting to provide generic parameter types with a C binding.
The reinterpret_cast<> here is a flag that lets you know you need to be careful, but it is not to be avoided at all costs.
If, on the other hand, you controlled both sides of the code, the API and the consumer, it would be better to make an API that was type-safe and did not require the consumer to perform casts to use it correctly.
Not to disrespect MSDN, but MSDN is not the best place to go for proper C++ coding.
One reason to use reinterpret_cast is when you're casting to/from opaque datatypes. reinterpret_cast is not "dangerous" it's just that it's easy to screw up and lead to problems in your code, which is why it should be avoided.
The reason why the C++ style casts are preferred are that, static_cast is typesafe, and all casting times are easier to search for.
Programmers [incorrectly] often use casts to "cast off compiler warnings" such as converting from unsigned to signed integers, or from a 32bit integer to an 8bit one.
Essentially reinterpret_cast is "safe" with C structures and basic types (baring plain mistakes like casting int to a pointer and back, which works on ILP32 architecture but breaks on LP64 one.) A C structure doesn't have anything in it, except possible padding for alignment, that you didn't declare.
reinterpret_cast is not safe with C++ polymorphic types since compiler inserts data items into your class - things like pointers to virtual tables and pointers to virtual base classes. Other C++ casts take care of adjusting these when, say, down-casting from pointer to base class to pointer to derived class, reinterpret_cast and C-style casts don't.
Related
A certain tutorial for the Win32 API uses this line to transform the lParam argument from a WM_CREATE message in the main window procedure into a CREATESTRUCT*:
reinterpret_cast<CREATESTRUCT*>(lParam) // Method 1
I've read elsewhere that reinterpret_cast is dangerous and results in undefined behavior, lightning bolts, and whatnot.
I've used a more conventional cast which the compiler doesn't complain about:
(CREATESTRUCT*) lParam // Method 2
Is there a reason the author of the tutorial did it their way?
And, I'm sure there's a better way than mine?
Both constructs are equivalent in this particular case. There is no undefined behavior -- the C++ standard guarantees that reinterpret-casting a pointer to a sufficiently wide integer and back results in the same pointer.
You can safely assume that Windows created the lParam value from the original pointer as if by reinterpret_cast.
"(CREATESTRUCT*) lParam" form is called a c-style cast. When this is used the compiler would try all possible ways to convert the expression (lParam - here) to the type (CREATESTRUCT* - here).
Let me explain all possible ways of casting,
Casting from "const/volatile T" to T - in C++ a programmer picks this way using const_cast
Casting from "T" to "R" where T and R are related. E.g. like int/char, Car/Vehicle etc. - in C++ a programmer picks this way of casting using static_cast.
Casting from "T" to "R" where T and R are related, along with runtime check. E.g. T = Vehicle and R = Car, conversion from T type object to R type object is valid statically but in reality (at runtime) compiler (through hidden code) has to check if the object being type-casted is indeed a Car or a derivative of Car. - in C++ a programmer picks this way of casting using dynamic_cast.
Casting from "U" to "V" where U and V are unrelated. - in C++ a programmer picks this way of casting using reinterpret_cast.
If a c-style cast is used in C++ by a programmer, he is telling the compiler to try all possible ways to convert/perceive an expression to/as a particular type.
The only reason c-style cast is dangerous is because the real intention of the programmer is not properly conveyed to the compiler and fellow programmers who would be reading the code. Sometimes a programmer may only have meant a static_cast and not reinterpret_cast but using a c-style cast would cause an error at run-time which could have been caught at compile time. Because compiler error would occur if the programmer uses static_cast on unrelated types.
And user defined cast operators affects some behaviors a bit more (esp. static_cast) but does not change the fundamentals.
In the WinAPI, WndProc has lParam and wParam which are longs. This means you generally have to typecast them into the correct type.
I've read that message systems in OOP should not need to cast things and that this is a bad practice. Therefore, in a language like C++, how would a basic message system work, where each message has 2 parameters, or even object pointers, depending on the message, but doing so without typecasting?
Thanks
For the general case I doubt you can do without some typecasting.
However, in C++ level design the typecasting can be mostly be centralized.
Look up visitor pattern.
Cheers & hth.,
The problem with type-casting is that it isn't safe. Boost provides a number of ways to do typecasting in a safe way.
If the data that could be sent in your message system is well-defined, limited to a few possible choices, then one could employ a boost::variant object. Variants are kind of like type-safe unions that have built-in visitation support.
However, if the set of possible data is more or less arbitrary, then you won't be able to use a variant. You still want to preserve type-safety, so that the person receiving the message cannot cast it to a different type other than the type that it was originally given with. In that case, boost::any is a good choice. Yes, you still have to use an any_cast, but that will fail if it is not of the proper type.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why do we have reinterpret_cast in C++ when two chained static_cast can do it's job?
I have been suggested that i should not use reinterpret_cast or const_cast in case of pointer to pointer conversion. Only dynamic_cast should be used.Because other cast can create problem in future. So my question is why not reinterpret_cast or other cast which is dangerous has been removed from c++ standard.
Because there are times when you need a cast which does what reinterpret_cast does. As for dynamic_cast, I almost never use this cast; that's only for casting from a parent type to a more derived type. Most of the time I can prove which child type I'm working with, and I use static_cast. I also use static_cast for compile time type conversions, for example from signed to unsigned integers.
static_cast, not dynamic_cast, is the most common kind of cast. If your design relies on dynamic_cast too heavily, that's a code smell indicating your class hierarchy violates LSP in most cases.
In the real world, you frequently have to cast pointers in ways the compiler/runtime can't validate. For example, in pthreads you pass a void* to the new thread's start routine. Sometimes that arg is actually a class? The compiler has no way to tell. It's one of those "real life" issues.
Incidentally I find myself using dynamic_cast infrequently. My main use for is has been exception type scraping in catch blocks.
They are dangerous but sometimes you need them.
C++ is not know for removing constructs that are dangerous to the new user. We will let you run with those scissors (while eating cake).
What makes them good is that the dangerous code sticks out so it is easy to spot. So when people do code reviews they can quickly spot the stuff that is dangerous and add a little scrutiny more checking.
Use reinterpret_cast for casting between unrelated pointer types.
Use static_cast for explicit, supported conversions.
Use dynamic_cast to cast a pointer of one type to a pointer of a derived type.
If you know a pointer to a parent type points to a child type, you can safely static_cast from the parent type to the child type. A cast from a child type pointer to a parent type pointer is implicit and requires no explicit cast.
A reinterpret_cast example from my own code base:
unsigned int CTaskManager::CWorker::WorkerMain(void* Parameters)
{
CWorker* This = reinterpret_cast<CWorker*>(Parameters);
// ...
}
bool CTaskManager::CWorker::Initialize()
{
// ...
// Create worker.
m_ThreadHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &(WorkerMain), this, 0, NULL));
// ...
}
A lot of dangerous operations, though they should generally be avoided, do have a rare legitimate usage. Furthermore, the rule of thumb when it comes to language features and APIs is that once it's there, you can't get rid of it; removing a feature from the C++ language has the potential to break lots of existing C++ code. Typically removal of features requires demonstration that it is not used or that the use is so limited that the cost impact of getting rid of it would be small. Even trigraphs, which are almost never used (unless you are at IBM) and which people wanted to get rid of survived the axe. These various casts and other usually dangerous operations are used way, way more than trigraphs are.
The reinterpret_cast as we know can cast any pointer type to any another pointer type. The question I want to ask regarding this cast operator are:
How does reinterpret_cast work, What is the magic(the internal implementation) that allows reinterpret_cast to work?
How to ensure safety when using reinterpret_cast? As far as i know, it doesn't guarantee of safe casting, So what precaution to take while using reinterpret_cast?
What is the practical usage of this operator. I have not really encountered it in my professional programing experience, wherein I could'nt get around without using this operator.Any practical examples apart from usual int* to char* will be highly helpful and appreciated.
One other Question regarding casting operators in general:
Casting operators(static_cast, dynamic_cast, const_cast, reinterpret_cast) are all called Operators i.e is to the best of my understanding, So is it correct statement to make that casting operators cannot be overloaded unlike most other operators (I am aware not all operators can be overloaded and I am aware of which can't be(except the Q I am asking, Please refrain flaming me on that) Just I had this doubt that since they are operators, what does the standard say about these?
There is no magic. reinterpret_cast normally just means (at least try to) treat what you find at this address as if it was the type I've specified. The standard defines little enough about what it does that it could be different from that, but it rarely (if ever) really is.
In a few cases, you can get safety from something like a discriminated union. For example, if you're reading network packets, and read enough to see that what you've received is a TCP packet, then you can (fairly) safely do a reinterpret_cast from IPHdr to TCPHdr (or whatever names you happen to have used). The compiler won't (again, normally) do much though -- any safety is up to you to implement and enforce.
I've used code like I describe in 2), dealing with different types of network packets.
For your final question: you can overload casting for a class:
class XXX {
public:
operator YYY() { return whatever; }
};
This can be used for conversions in general though -- whether done by a static_cast, C-style cast, or even an implicit conversion. C++0x allows you to add an explicit qualifier so it won't be used for implicit conversions, but there's still no way to differentiate between a static_cast and a C-style cast though.
First, it's unclear what you mean by "non-standard pointer". I think your premise is flawed. Happily it doesn't seem to affect the questions.
"How does [it] work?" Well, the intent, as you can guess from the name, is to just change the interpretation of a bitpattern, perhaps extending or shorting as appropriate. This is a kind of change of type where the bitpattern is left unchanged but the interpretation and hence conceptual value is changed. And it's in contrast to a kind of change of type where the conceptual value is kept (e.g. int converted to double) while the bitpattern is changed as necessary to keep the conceptual value. But most cases of reinterpret_cast have implementation defined effect, so for those cases your compiler can do whatever it wants -- not necessarily keeping the bitpattern -- as long as it is documented.
"How to ensure safety" That is about knowing what your compiler does, and about avoiding reinterpret_cast. :-)
"What is the practical usage". Mostly it is about recovering type information that's been lost in C-oriented code where void* pointers are used to sort of emulate polymorphism.
Cheers & hth.,
reinterpret_cast generally lets you do some very bad things. In the case of casting a pointer it will permit casting from one type to another which has absolutely no reason to assume this should work. It's like saying "trust me I really want to do this". What exactly this does is unpredictable from one system to the next. On your system it might just copy the bit-patterns, where as on another one it could transform them in some (potentially useful) way.
e.g.
class Foo {
int a;
};
class Bar {
int a;
};
int main() {
Foo a;
// No inheritance relationship and not void* so must be reinterpret_cast
// if you really want to do it
Bar *b = reinterpret_cast<Bar*>(&a);
char buffer[sizeof(Bar)];
Bar *c = reinterpret_cast<Bar*>(buffer); // alignment?
}
Will quite happily let you do that, no matter what the scenario. Sometimes if you're doing low-level manipulation of things this might actually be what you want to do. (Imagine char * of a buffer casting to something user defined type)
Potential pitfalls are huge, even in the simplest case like a buffer, where alignment may well be a problem.
With dlsym() on Linux it's useful to be able to cast void* to a function pointer, which is otherwise undefined behaviour in C++. (Some systems might use separate address spaces or different size pointers!). This can only be done with reinterpret_cast in C++.
reinterpret_cast only works on pointers. The way it works is that it leaves the value of the pointer alone and changes the assumed type information about it. It says, "I know these types are not equivalent, but I want you to just pretend this is now a pointer to T2." Of course, this can cause any number of problems if you use the T2 pointer and it does not point to a T2.
There are very few guarantees about reinterpret_cast, which is why it is to be so avoided. You're really only allowed to cast from T1 to T2 and then back to T1 and know that, given some assumptions, that the final result will be the same as what you started with.
The only one I can think of is casting a char* to an unsigned char*. I know that the underlying representation is the same in my implementation so I know the cast is safe. I can't use a static cast though because it's a pointer to a buffer. In reality, you'll find very little legitimate use of reinterpret_cast in the real world.
Yes, they are operators. AFAIK you can't override them.
One "practical" use of reinterpret_cast.
I have a class where the members are not meant to be read. Example below
class ClassWithHiddenVariables
{
private:
int a;
double m;
public:
void SetVariables(int s, int d)
{
a = s;
m = d;
}
};
This class is used in a thousand places in an application without a problem.
Now, because of some reason I want see the members in one specific part. However, I don't want to touch the existing class.So break the rules as follows.
Create another class with the same bit pattern and public visibility. Here the original class contains an int and double.
class ExposeAnotherClass
{
public:
int a_exposed;
double m_exposed;
};
When you want to see members of the ClassWithHiddenVariables object, use reinterpret_cast to cast to ExposeAnotherClass. Example follows
ClassWithHiddenVariables obj;
obj.SetVariables(10, 20.02);
ExposeAnotherClass *ptrExposedClass;
ptrExposedClass = reinterpret_cast<ExposeAnotherClass*>(&obj);
cout<<ptrExposedClass->a_exposed<<"\n"<<ptrExposedClass->m_exposed;
I don't think this situation ever occurs in real world. But this is just an explanation of reinterpret_cast which considers objects as bit patterns.
reinterpret_cast tells the compiler "shut up, it's a variable of type T*" and there's no safety unless it is really a variable of type T*. On most implementations just nothing is done - the same value in the variable is passed to the destination.
Your class can have conversion operators to any type T* and those conversions will either be invokde implicitly under certain conditions or you can invoke them explicitly using static_cast.
I've used reinterpret_cast a lot in Windows programming. Message handling uses WPARAM and LPARAM parameters that need casting to the correct types.
reinterpret_cast is pretty equivalent to a C-style cast. It doesn't guarentee anything; it's there to allow you to do what you need to, in the hopes that you know what you're doing.
If you're looking to ensure safety, use dynamic_cast, as that's what it does. If the cast cannot be completed safely, dynamic_cast returns NULL or nullptr (C++0x).
Casting using the "casting operators" such as static_cast, dynamic_cast, etc.. cannot be overloaded. Straight conversions can, such as:
class Degrees
{
public:
operator double() { ... }
};
The reinterpret_cast as we know can
cast any non-standard pointer to
another non-standard pointer.
Almost, but not exactly. For example, you can't use reinterpret_cast to cast a const int* to an int*. For that, you need const_cast.
How does reinterpret_cast work, What is the magic(the internal
implementation) that allows
reinterpret_cast to work?
There's no magic at all. Ultimately, all data is just bytes. The C++ type system is merely an abstraction layer which tells the compiler how to "interpret" each byte. A reinterpret_cast is similar to a plain C-cast, in that it simply says "to hell with the type system: interpret these bytes as type X instead of type Y!"
How to ensure safety when using reinterpret_cast? As far as i know, it
doesn't guarantee of safe casting, So
what precaution to take while using
reinterpret_cast?
Well, reinterpret_cast is inherently dangerous. You shouldn't use it unless you really know what you're doing. Try to use static_cast instead. The C++ type system will protect you from doing anything too dangerous if you use static_cast.
What is the practical usage of this operator. I have not really
encountered it in my professional
programing experience, wherein I
could'nt get around without using this
operator.Any practical examples apart
from usual int* to char* will be
highly helpful and appreciated.
It has many uses, but usually these uses are somewhat "advanced". For example, if you are creating a memory pool of linked blocks, and storing pointers to free blocks on the blocks themselves, you'll need to reinterpret_cast a block from a T* to a T** to interpret the block as a pointer to the next block, rather than a block itself.
My knowledge of C++ at this point is more academic than anything else. In all my reading thus far, the use of explicit conversion with named casts (const_cast, static_cast, reinterpret_cast, dynamic_cast) has come with a big warning label (and it's easy to see why) that implies that explicit conversion is symptomatic of bad design and should only be used as a last resort in desperate circumstances. So, I have to ask:
Is explicit conversion with named casts really just jury rigging code or is there a more graceful and positive application to this feature? Is there a good example of the latter?
There're cases when you just can't go without it. Like this one. The problem there is that you have multiple inheritance and need to convert this pointer to void* while ensuring that the pointer that goes into void* will still point to the right subobject of the current object. Using an explicit cast is the only way to achieve that.
There's an opinion that if you can't go without a cast you have bad design. I can't agree with this completely - different situations are possible, including one mentioned above, but perhaps if you need to use explicit casts too often you really have bad design.
There are situations when you can't really avoid explicit casts. Especially when interacting with C libraries or badly designed C++ libraries (like the COM library sharptooth used as examples).
In general, the use of explicit casts IS a red herring. It does not necessarily means bad code, but it does attract attention to a potential dangerous use.
However you should not throw the 4 casts in the same bag: static_cast and dynamic_cast are frequently used for up-casting (from Base to Derived) or for navigating between related types. Their occurrence in the code is pretty normal (indeed it's difficult to write a Visitor Pattern without either).
On the other hand, the use of const_cast and reinterpret_cast is much more dangerous.
using const_cast to try and modify a read-only object is undefined behavior (thanks to James McNellis for correction)
reinterpret_cast is normally only used to deal with raw memory (allocators)
They have their use, of course, but should not be encountered in normal code. For dealing with external or C APIs they might be necessary though.
At least that's my opinion.
How bad a cast is typically depends on the type of cast. There are legitimate uses for all of these casts, but some smell worse than others.
const_cast is used to cast away constness (since adding it doesn't require a cast). Ideally, that should never be used. It makes it easy to invoke undefined behavior (trying to change an object originally designated const), and in any case breaks the const-correctness of the program. It is sometimes necessary when interfacing with APIs that are not themselves const-correct, which may for example ask for a char * when they're going to treat it as const char *, but since you shouldn't write APIs that way it's a sign that you're using a really old API or somebody screwed up.
reinterpret_cast is always going to be platform-dependent, and is therefore at best questionable in portable code. Moreover, unless you're doing low-level operations on the physical structure of objects, it doesn't preserve meaning. In C and C++, a type is supposed to be meaningful. An int is a number that means something; an int that is basically the concatenation of chars doesn't really mean anything.
dynamic_cast is normally used for downcasting; e.g. from Base * to Derived *, with the proviso that either it works or it returns 0. This subverts OO in much the same way as a switch statement on a type tag does: it moves the code that defines what a class is away from the class definition. This couples the class definitions with other code and increases the potential maintenance load.
static_cast is used for data conversions that are known to be generally correct, such as conversions to and from void *, known safe pointer casts within the class hierarchy, that sort of thing. About the worst you can say for it is that it subverts the type system to some extent. It's likely to be needed when interfacing with C libraries, or the C part of the standard library, as void * is often used in C functions.
In general, well-designed and well-written C++ code will avoid the use cases above, in some cases because the only use of the cast is to do potentially dangerous things, and in other cases because such code tends to avoid the need for such conversions. The C++ type system is generally seen as a good thing to maintain, and casts subvert it.
IMO, like most things, they're tools, with appropriate uses and inappropriate ones. Casting is probably an area where the tools frequently get used inappropriately, for example, to cast between an int and pointer type with a reinterpret_cast (which can break on platforms where the two are different sizes), or to const_cast away constness purely as a hack, and so on.
If you know what they're for and the intended uses, there's absolutely nothing wrong with using them for what they were designed for.
There is an irony to explicit casts. The developer whose poor C++ design skills lead him to write code requiring a lot of casting is the same developer who doesn't use the explicit casting mechanisms appropriately, or at all, and litters his code with C-style casts.
On the other hand, the developer who understands their purpose, when to use them and when not to, and what the alternatives are, is not writing code that requires much casting!
Check out the more fine-grained variations on these casts, such as polymorphic_cast, in the boost conversions library, to give you an idea of just how careful C++ programmers are when it comes to casting.
Casts are a sign that you're trying to put a round peg in a square hole. Sometimes that's part of the job. But if you have some control over both the hole and the peg, it would be better not create this condition, and writing a cast should trigger you to ask yourself if there was something you could have done so this was a little smoother.