Is reinterpret_cast <char *> the only valid use of reinterpret_cast?

I recently learned that the C ++ standard contains “strict alias rules” that prohibit reference to the same memory location through variables of different types.

However, the standard allows char types to legally aliases of any other type. Does this mean that reinterpret_cast can only be legally used to cast char * or char & ?

I believe that strict pseudo-reduction allows us to distinguish between types in the inheritance hierarchy, but I think that these situations will tend to use dynamic_cast <>?

thanks

+7
c ++ strict-aliasing
source share
3 answers

There are many different uses for reinterpret_cast . The cppreference page lists 11 different cases.

I think you only ask about cases 5 and 6: casting T * to U * and dropping T to U & .

In these cases, the cast is legal until alignment is broken. A severe problem with an alias only occurs if you are reading or writing the resulting expression.

Your summary of the strict anti-aliasing rule in your first paragraph is a big simplification, in general there are several legal types for U On the same cppreference page, a bulleted list of cases is displayed; you can read the exact text of the rule in a standard C ++ draft.

+9
source share

You can also use reinterpret_cast to convert a pointer type to an integer type:

 char* ptr = /* ... */ uintptr_t ptrInt = reinterpret_cast<uintptr_t>(ptr); 

The specific integer value you return is not portable across platforms, but it is a safe and well-defined operation.

+5
source share

There are other options for using reinterpret_cast .

Pointer to an integer type

Yes, at some point I would like to save the value of the pointer in an integer type.

The only way to do this with C ++ style styles is with reinterpret_cast .

Example:

 auto pointerValue = reinterpret_cast<std::uintptr_t>(pointer); 

Saving objects in a raw block of memory

Sometimes you want to store data on the stack, but initialize it later. Using dynamic allocations and pointers will not use the stack. std::aligned_storage works great as a source, aligned memory block.

 struct MyStruct { int n; std::string s; }; // allocated on automatic storage std::aligned_storage<sizeof(MyStruct), alignof(MyStruct)>::type storage; // actually initialize the object new (&storage) MyStruct; // using the object reinterpret_cast<MyStruct*>(&storage)->n = 42; 

I am sure there are many other uses that I don’t know, but this is the one that I have already used.

+5
source share

All Articles