What is the meaning of reinterpret cast?

In C++, there is an operator reinterpret_cast, the meaning of which is to cast between types that are incompatible with each other.

However, such transformations violate strict aliasing rule, which provokes undefined behavior. The same transformations that do not violate this rule are placed in const_cast, static_cast and dynamic_cast.

What, then, is the meaning of the existence of this operator, if its use violates the standard?

Author: Arhadthedev, 2017-09-09

3 answers

reinterpret_cast it is used not only for converting pointers of one type to another. There are several different transformations. cppreference.com highlights 11 conversion options:

  1. In its own type
  2. A pointer to the integral type
  3. of integral type to the pointer
  4. Type std::nullptr_t to integral type
  5. A pointer of one type to a pointer of another type
  6. lvalue of one type to a reference to another type
  7. A pointer to a function of one type to a pointer to a function of another type
  8. A pointer to a function in void*
  9. A null pointer of any type to a pointer of any other type
  10. rvalue a pointer of one type to a member function to a pointer of another type to a member function
  11. rvalue pointer of a data member of one type to a pointer to another data member of another type

Type aliasing-the rules only affect items 5 and 6 and the result can be safely used (i.e. without violating strict-aliasing) in the following cases:

  • The resulting type is the dynamic type of the source object
  • The resulting type and the dynamic type point to the same type T
  • The resulting type is a signed or unsigned variant of the source object type
  • The resulting type is an aggregate type or union, which contains an element or a non-static data member that is used as the source object. I.e., you can get a pointer to a structure by pointing to its member.
  • The result type is the base class of the dynamic type of the source object and this type is a standard-layout class and does not contain non-static data members, and the result type is the first base class.
  • The resulting type is a pointer to char, unsigned char or std::byte.

Some implementations relax these rules as non-standard language extensions.

 10
Author: αλεχολυτ, 2017-09-22 16:12:04

There is exactly one type of conversion between incompatible types that does not violate the strict aliasing rule - from an arbitrary pointer to a pointer of type char*. That is, reinterpret_cast allows you to represent an arbitrary object as a sequence of bytes (since the standard guarantees a single-byte length of char - a).

Here is an example of proper use of this type of conversion:

template<class T>
void putIntoStream(const T* object, std::ostream& out)
{
    out.write(reinterpret_cast<const char*>(object), sizeof(T));
}

For everything else, there is memcpy().

 4
Author: Arhadthedev, 2017-09-09 08:22:40

Although using reinterpret_cast in most cases results in undefined behavior, libraries can use it in their implementations by testing them for specific compilers. For the user of libraries, the behavior will no longer be undefined, since it is checked and documented, but he will have to take into account the list of supported compilers. Sometimes this is the only way to develop a cross-platform library.

In addition, there are still cases where you have to sacrifice portability to achieve other goals (in particular, this is true for microcontrollers).

 2
Author: Ariox, 2017-09-09 08:34:01