Reputation: 20332
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)
Upvotes: 12
Views: 729
Reputation: 6157
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.
Upvotes: 3
Reputation: 84239
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.
Upvotes: 2
Reputation: 46903
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.
Upvotes: 2
Reputation: 71063
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.
Upvotes: 5
Reputation: 7959
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."
Upvotes: 8