Telegram Group & Telegram Channel
#madskillz

Напиши свой собственный RTTI 🖱

RTTI (run-time type information) это некая информация о всех виртуальных классах, которая попадает в бинарник программы.
Благодаря этому работают dynamic_cast<> (приведение типа в run-time) и typeid.
Генерацию RTTI можно выключить флагом компиляции -fno-rtti.

Пусть у нас есть указатель X* x (или ссылка X& x). Указатель может указывать на объект с типом не X (но это обязательно будет тип-потомок X).

Есть три варианта приведений типа X к типу Y (тип Y тоже не обязательно реальный тип объекта):

1️⃣Upcast: Y - класс-предок X.
Для этого не требуется никакого RTTI. Такое приведение всегда возможно. Можно было бы обойтись static_cast<> (приведение типа в compile-time).

2️⃣ Downcast: Y - класс-потомок X.
В этом случае обычно используют dynamic_cast<>. Если окажется, что тип объекта не Y (или не какого-то потомка Y), то приведения не случится.

Интересно, что если программист совершенно уверен, что приведение возможно, то можно использовать static_cast<> и не делать run-time проверку. Если окажется, что он был не прав, то получится undefined behaviour 😁

3️⃣ Sidecast: X и Y никак не связаны между собой.
Такое возможно, если X* указывает на объект класса Z:
class Z : public X, public Y {...};
Такие касты dynamic_cast<> тоже умеет делать.
Скорее всего sidecast значит, что в программе есть серьезные ошибки дизайна 🧐

Некоторые проекты не используют "официальный" RTTI 😡
Почему так происходит, на примере очень популярных проектов:

1️⃣ Protobuf: вынужденная поддержка проектов с -fno-rtti.

В protobuf есть базовый для всех "месседжей" класс google::protobuf::Message.

Чтобы попробовать сделать downcast от базового класса до класса "месседжа", можно использовать функцию DynamicCastToGenerated.
Как видно по исходнику, если уж нельзя вызвать dynamic_cast<>, то используется костыль - суррогат RTTI: сравнение ссылки на "рефлексию" (уникальное описание "месседжа"). Эту ссылку возвращает виртуальный метод.

Какие ограничения этого подхода: С -fno-rtti доступен только downcast строго на указанный класс - потомок класса Message.

2️⃣ LLVM: своя реализация RTTI для быстродействия.

Clang и LLVM имеют большую иерархию типов и делают огромную кучу проверок на типы. Большая часть кода в компиляторах (оптимизации, кодогенерация, ...) завязана на поиск специфических паттернов и операциях на них. Для этого необходимо проверять тип объектов в овер9000 местах, поэтому быстродействие dynamic_cast становится узким местом.

А быстродействие у dynamic_cast сравнительно плохое. Он должен делать обход иерархии наследования и вычисляет путь обхода динамическим образом. Это на несколько порядков медленнее, чем просто вызвать виртуальный метод и что-то сравнить.

В документации есть крутая статья, как сделать свой RTTI "почти как в LLVM" - How to set up LLVM-style RTTI for your class hierarchy. Для этого заводится специальный enum, и каждый класс реализует статический метод classof. Вместо обхода иерархии наследования делается один вызов виртуального метода!

Какие ограничения этого подхода: Дополнительный код - enum, статический метод в каждом классе. Нужно следить за тем, чтобы соответствие между enum и классами не разломалось (хотя тут могут помочь кодогенераторы). Эта схема работает, только если иерархия классов известна заранее (стандартный C++ RTTI такого не требует).

Всего известно три главных аргумента "против RTTI":
🅱️ Занимает память в бинарнике - очень сомнительный аргумент. RTTI не требует столько памяти, чтобы это стало заметно, по крайней мере в 2023 году.
🅱️ Медленно работает - хороший аргумент, если dynamic_cast<> является узким местом в программе. Но это должна быть специфическая программа, как поиск паттернов в структурах с большой иерархией классов... (например, компилятор C++)
🅱️ Его использование - ошибка дизайна - неожиданный аргумент, но именно по этой причине RTTI запрещен в Google C++ Style Guide. По ссылке есть описание "почему это плохо". Конечно, из каждого правила есть исключение.
Please open Telegram to view this post
VIEW IN TELEGRAM



group-telegram.com/cxx95/94
Create:
Last Update:

#madskillz

Напиши свой собственный RTTI 🖱

RTTI (run-time type information) это некая информация о всех виртуальных классах, которая попадает в бинарник программы.
Благодаря этому работают dynamic_cast<> (приведение типа в run-time) и typeid.
Генерацию RTTI можно выключить флагом компиляции -fno-rtti.

Пусть у нас есть указатель X* x (или ссылка X& x). Указатель может указывать на объект с типом не X (но это обязательно будет тип-потомок X).

Есть три варианта приведений типа X к типу Y (тип Y тоже не обязательно реальный тип объекта):

1️⃣Upcast: Y - класс-предок X.
Для этого не требуется никакого RTTI. Такое приведение всегда возможно. Можно было бы обойтись static_cast<> (приведение типа в compile-time).

2️⃣ Downcast: Y - класс-потомок X.
В этом случае обычно используют dynamic_cast<>. Если окажется, что тип объекта не Y (или не какого-то потомка Y), то приведения не случится.

Интересно, что если программист совершенно уверен, что приведение возможно, то можно использовать static_cast<> и не делать run-time проверку. Если окажется, что он был не прав, то получится undefined behaviour 😁

3️⃣ Sidecast: X и Y никак не связаны между собой.
Такое возможно, если X* указывает на объект класса Z:

class Z : public X, public Y {...};
Такие касты dynamic_cast<> тоже умеет делать.
Скорее всего sidecast значит, что в программе есть серьезные ошибки дизайна 🧐

Некоторые проекты не используют "официальный" RTTI 😡
Почему так происходит, на примере очень популярных проектов:

1️⃣ Protobuf: вынужденная поддержка проектов с -fno-rtti.

В protobuf есть базовый для всех "месседжей" класс google::protobuf::Message.

Чтобы попробовать сделать downcast от базового класса до класса "месседжа", можно использовать функцию DynamicCastToGenerated.
Как видно по исходнику, если уж нельзя вызвать dynamic_cast<>, то используется костыль - суррогат RTTI: сравнение ссылки на "рефлексию" (уникальное описание "месседжа"). Эту ссылку возвращает виртуальный метод.

Какие ограничения этого подхода: С -fno-rtti доступен только downcast строго на указанный класс - потомок класса Message.

2️⃣ LLVM: своя реализация RTTI для быстродействия.

Clang и LLVM имеют большую иерархию типов и делают огромную кучу проверок на типы. Большая часть кода в компиляторах (оптимизации, кодогенерация, ...) завязана на поиск специфических паттернов и операциях на них. Для этого необходимо проверять тип объектов в овер9000 местах, поэтому быстродействие dynamic_cast становится узким местом.

А быстродействие у dynamic_cast сравнительно плохое. Он должен делать обход иерархии наследования и вычисляет путь обхода динамическим образом. Это на несколько порядков медленнее, чем просто вызвать виртуальный метод и что-то сравнить.

В документации есть крутая статья, как сделать свой RTTI "почти как в LLVM" - How to set up LLVM-style RTTI for your class hierarchy. Для этого заводится специальный enum, и каждый класс реализует статический метод classof. Вместо обхода иерархии наследования делается один вызов виртуального метода!

Какие ограничения этого подхода: Дополнительный код - enum, статический метод в каждом классе. Нужно следить за тем, чтобы соответствие между enum и классами не разломалось (хотя тут могут помочь кодогенераторы). Эта схема работает, только если иерархия классов известна заранее (стандартный C++ RTTI такого не требует).

Всего известно три главных аргумента "против RTTI":
🅱️ Занимает память в бинарнике - очень сомнительный аргумент. RTTI не требует столько памяти, чтобы это стало заметно, по крайней мере в 2023 году.
🅱️ Медленно работает - хороший аргумент, если dynamic_cast<> является узким местом в программе. Но это должна быть специфическая программа, как поиск паттернов в структурах с большой иерархией классов... (например, компилятор C++)
🅱️ Его использование - ошибка дизайна - неожиданный аргумент, но именно по этой причине RTTI запрещен в Google C++ Style Guide. По ссылке есть описание "почему это плохо". Конечно, из каждого правила есть исключение.

BY C++95


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/cxx95/94

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

For Oleksandra Tsekhanovska, head of the Hybrid Warfare Analytical Group at the Kyiv-based Ukraine Crisis Media Center, the effects are both near- and far-reaching. The message was not authentic, with the real Zelenskiy soon denying the claim on his official Telegram channel, but the incident highlighted a major problem: disinformation quickly spreads unchecked on the encrypted app. But Kliuchnikov, the Ukranian now in France, said he will use Signal or WhatsApp for sensitive conversations, but questions around privacy on Telegram do not give him pause when it comes to sharing information about the war. Founder Pavel Durov says tech is meant to set you free Following this, Sebi, in an order passed in January 2022, established that the administrators of a Telegram channel having a large subscriber base enticed the subscribers to act upon recommendations that were circulated by those administrators on the channel, leading to significant price and volume impact in various scrips.
from sg


Telegram C++95
FROM American