static_cast and reinterpret_cast for std::aligned_storage
Asked Answered
N

1

11

could someone please explain the bit of code about casting in http://en.cppreference.com/w/cpp/types/aligned_storage please?

can the following code

return *static_cast<const T*>(static_cast<const void*>(&data[pos]));

be replaced with

 return *reinterpret_cast<const T*>(&data[pos]);

?

Why here two casting are used? Thanks a lot.

Hong

Neddie answered 10/10, 2013 at 15:32 Comment(5)
I suspect this is something that's required for proper portability / standard conformance because the result of reinterpret_cast isn't specified in the standard. In practice they probably do the same thing in all or almost all implementations.Monomer
The two are equivalent in C++11.Parhe
@SteveJessop: I think that's an answer.Cuff
@JohnDibling: it would be if I was sure that it's correct (first that reinterpret_cast is under-specified for the job, and second that this is the reason that example code uses those two casts). It's a bit of a poor showing, if std::aligned_storage really does give you something that's two casts away from being usable.Monomer
I first used reinterpret_cast in that cppreference example but then changed to this static_cast chain with the comment 'avoid formal UB' after reading the Lounge discussion starting from chat.stackoverflow.com/transcript/message/10437436#10437436 and the TR1-age post https://mcmap.net/q/1006094/-what-is-the-basic-use-of-aligned_storage .. but I may have been overly cautious. Feel free to change back if someone posts a convincing answer.Lyricism
H
5

According to the standard (§ 5.2.10 reinterpret_cast, section 7):

A pointer to an object can be explicitly converted to a pointer to a different object type. When a prvalue v of type “pointer to T1” is converted to the 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 are no stricter than those of T1.

Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

So, we could make the following conclusion:

  1. reinterpret_cast<*T>(ptr) is eqiuvalent to static_cast<*T>(static_cast<void*>(ptr))
  2. static_cast<>(ptr) is not always equal to ptr, but reinterpret_cast<>(ptr) is always equal to ptr
  3. if there is no alignment issues, we can use reinterpret_cast safely
Humo answered 28/10, 2013 at 14:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.