Should I use it or static_cast <void *> and then static_cast <myType *> to avoid reinterpret_cast?

I saw people suggest using static_cast<SomeType*>(static_cast<void*>(p)) rather than reinterpreting casting.

I do not understand why this is better, can someone explain?

For the argument, here is an example script that requires reinterpret_cast:

 DWORD lpNumberOfBytes; ULONG_PTR lpCompletionKey; LPOVERLAPPED lpOverlapped; GetQueuedCompletionStatus(myHandle, &lpNumberOfBytes, &lpCompletionKey, &lpOverlapped, 0); if(lpCompletionKey == myCustomHandlerKey){ auto myObject = reinterpret_cast<MyObject*>(lpOverlapped); //i know this is really a MyObject } 

This is what I heard suggested:

 auto myObject = static_cast<MyObject*>(static_cast<void*>(lpOverlapped)); 

Edit: I started my question with The comments section of "asdf" suggests using static_cast instead of reinterpret_cast here http://blogs.msdn.com/b/vcblog/archive/2014/02/04/challenge-vulnerable-code.aspx but in retrospect the fact that my question came from there doesn't matter.

+6
source share
2 answers

ยง5.2.10 describes the legal comparisons that reinterpret_cast can perform, and indicates that "no other conversion can be performed."

For your example, the / 7 transform is used:

A pointer to an object can be explicitly converted to a pointer to another type of object. When prvalue v type "pointer to T1 " is converted to type "pointer to cv T2 ", the result is static_cast< cv T2*>(static_cast<cv void*>(v)) , if both T1 and T2 are standard, layout types .. . and the alignment requirements of T2 no more stringent than the requirements of T1 . [emphasis mine]

The result of the conversion of any other pointer to object types is "unspecified". 1

This is one of two reasons why reinterpret_cast is dangerous: its conversion is only correct for a subset of pointers to object types, and compilers usually do not offer any diagnosis of accidental abuse.

The second reason is that the compiler does not even check whether the mapping you are trying to perform is first and foremost legal, and which of the many (semantically completely different) comparisons will be performed.

It is better to be explicit and tell the compiler (and reader) that the intended conversion is what you want to perform. However, the asdfs comment is not entirely correct, since not all conversions you can perform with reinterpret_cast are equivalent to using static_cast<void*> , followed by static_cast to the target type.


1 In addition: in a nutshell (and a little simplified), the "standard layout type" is a type (or an array of type) that does not have virtual functions or visibility of a mixed element, and all its elements and bases are also standard. A type alignment is a restriction on the addresses in memory in which it can be located. For example, many machines require double be aligned at addresses divisible by 8.

+7
source

asdf explained this quite well, even if briefly in a related post.

because the compiler does not know that CustomImage comes from Image at this point in the program.

Personally, I can not bother to download garbage from msdn, just to delve into and answer the question. In the end, this is a coding problem, you have to understand this.

My rules for casting in C ++:

  • using C ++ style cast xx_cast<T*> rather than C-style (T*) , for explicit is better than implicit.
  • use reinterpret when you really understand it.
  • if you use reinterpret_cast<T*> , make sure cast / uncast is an exact mirror, for example:

.

 T* obj = ...; void* tmp = reinterpret_cast<void*> obj; T* ref = reinterpret_cast<T*> tmp; // T* obj --> T* ref 

Here you must make sure that obj and ref are of the same exact type, including constant constructors, class derivation, alignment, memory type (built-in), absolutely everything you can think of.

+2
source

All Articles