Страницы

Поиск по вопросам

среда, 31 октября 2018 г.

В чём смысл существования reinterpret_cast?

В C++ существует оператор reinterpret_cast, смысл которого заключается в приведении между типами, несовместимыми друг с другом.
Однако подобные преобразования нарушают strict aliasing rule, что провоцирует неопределённое поведение. Те же преобразования, которые этого правила не нарушают, укладываются в const_cast, static_cast и dynamic_cast
В чём же тогда заключается смысл существования данного оператора, если его использование нарушает стандарт?


Ответ

reinterpret_cast используется не только для преобразования указателей одного типа в другой. Существует несколько разных преобразований. cppreference.com выделяет 11 вариантов преобразований:
В свой собственный тип Указателя в интегральный тип Интегрального типа в указатель Типа std::nullptr_t в интегральный тип Указателя одного типа в указатель другого типа lvalue одного типа в ссылку на другой тип Указателя на функцию одного типа в указатель на функцию другого типа Указателя на функцию в void* Нулевого указателя любого типа в указатель любого другого типа rvalue указатель одного типа на функцию-член в указатель другого типа на функцию-член rvalue указатель члена-данных одного типа в указатель ну другой член-данных другого типа
Type aliasing-правила затрагивают только пункты 5 и 6 и результат может быть безопасно использован (т.е. без нарушения strict-aliasing) в следующих случаях:
Результирующий тип есть динамический тип исходного объекта Результирующий тип и динамический тип указывают на одинаковый тип T Результирующий тип есть знаковый или беззнаковый вариант типа исходного объекта Результирующий тип есть агрегатный тип или union, в котором содержится элемент или нестатический член данных, используемый в качестве исходного объекта. Т.е. можно получить указатель на структуру по указателю на её член. Результирующий тип есть базовый класс динамического типа исходного объекта и этот тип является standard-layout классом и не содержит нестатических членов-данных, и результирующий тип - первый базовый класс. Результирующий тип есть указатель на char, unsigned char или std::byte
Некоторые реализации ослабляют эти правила в качестве нестандартных расширений языка.

Комментариев нет:

Отправить комментарий