В 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
Некоторые реализации ослабляют эти правила в качестве нестандартных расширений языка.
Комментариев нет:
Отправить комментарий