RTTI и переносимость в C++

Если компилятор не «поддерживает» RTTI, означает ли это, что компилятор не может обрабатывать иерархии классов, в которых есть виртуальные функции? Или я неправильно понял литературу о том, что RTTI не является переносимым, а проблемы лежат в другом месте?

Спасибо всем за ваши комментарии!


person Joshua    schedule 25.04.2010    source источник
comment
Если компилятор не поддерживает RTTI, это не компилятор C++ — RTTI не является обязательным.   -  person    schedule 26.04.2010
comment
@Neil: Это бесполезный критерий для измерения компиляторов. Поддержка экспорта шаблонов также не является обязательной.   -  person Ben Voigt    schedule 26.04.2010
comment
Это будет необязательным именно потому, что export на самом деле был бесполезным мерилом. RTTI является не более необязательным, чем int.   -  person MSalters    schedule 26.04.2010


Ответы (4)


RTTI не нужен для виртуальных функций.

Он в основном используется для dynamic_cast и typeid.

person Thomas    schedule 25.04.2010
comment
Слишком долго писал C#, исправлено. Спасибо! - person Thomas; 26.04.2010

Это, вероятно, больше ответа, который вы искали, но вот:

RTTI не является "переносимым" означает, что если вы используете компилятор A для создания динамической библиотеки A и используете компилятор B для создания приложения B, которое связывается с A, то вы не можете использовать RTTI, поскольку реализации RTTI компилятора a и b различны. Виртуальные функции затрагиваются только потому, что механизм виртуальных функций также может быть несовместим с двоичными кодами.

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

Что изменилось между серединой 90-х и сейчас, так это разное отношение к тому, что составляет ценную интеллектуальную собственность, а что нет. А именно: на самом деле в USPO зарегистрирован патент на «шаблоны выражений». Даже владелец такого понимает, что патент не имеет исковой силы.

Библиотеки заголовков и двоичных файлов в стиле C долгое время рассматривались как способ запутать ценный исходный код. Бизнес все больше и больше приходил к пониманию того, что запутывание было скорее саморазрушительным, чем защитным: существует очень мало кода, который соответствует статусу «ценной ИС». Большинство людей покупают библиотеки не из-за специальных IP-адресов, которые они содержат, а потому, что дешевле купить, чем создавать свои собственные. На самом деле: опыт применения ИС гораздо ценнее, чем сама ИС. Но если этот IP никому не интересен, потому что о нем не знают, то он мало что стоит.

Вот как работает открытый исходный код: интеллектуальная собственность распространяется бесплатно, а взамен эти дистрибьюторы получают плату за консультационные услуги при применении этой интеллектуальной собственности. Те, кто может понять это для себя выгодно – хорошо на них. Но это не норма. На самом деле происходит то, что разработчик понимает ИС и продает своему работодателю покупку продукта, который ее реализует. Да, целые «сообщества разработчиков» основаны на этой предпосылке.

Короче говоря: бинарная (и впоследствии RTTI) совместимость ушла в прошлое, как только началось движение за открытый исходный код, и одновременно библиотеки шаблонов C++ стали нормой. Библиотеки C++ давно стали "исходными дистрибутивами", такими как Perl, Python, JavaScript и т. д. Чтобы ваш компилятор C++ работал со всем исходным кодом, который вы компилируете с его помощью, убедитесь, что RTTI включен (включая все стандартные функции C++, такие как исключения) , и что все библиотеки C++, на которые вы ссылаетесь, также скомпилированы с теми же параметрами, которые вы использовали для компиляции своего приложения.

Я знаю один (и только один) компилятор, который не включает RTTI по ​​умолчанию, и это потому, что есть другие устаревшие способы сделать то же самое. Чтобы прочитать об этом, возьмите экземпляр отличной работы Дона Бокса «Essential COM».

person Lance Diduck    schedule 25.04.2010
comment
эм.... Вау. На самом деле это многое объясняет. Мне всегда было интересно, почему в литературе по cs в конце концов описывается, как разделение заголовков и кода позволяет независимым поставщикам программного обеспечения создавать байты библиотек, которые можно продавать и повторно использовать, но, похоже, не хватало библиотек, которые вам не нужно было компилировать самостоятельно. Я хотел бы отметить два ответа, но мне нужно помнить, что нельзя задавать слишком много вопросов в одном посте. Спасибо за ваше понимание! - person Joshua; 27.04.2010
comment
Хотя я должен спросить, как ваш 5-й абзац связан с открытым и закрытым исходным кодом? Нельзя ли то же самое сделать в системе с закрытым исходным кодом? Или дело в том, что в системе с открытым исходным кодом больше возможностей для участия, создавая более надежную консультационную сеть (и, следовательно, это одна из конкретных причин, почему открытый исходный код работает?)? - person Joshua; 27.04.2010
comment
Есть еще несколько мест, таких как DinkumWare и RogueWave, которые лицензируют проприетарный исходный код C++ (то есть закрытый исходный код). Отличие заключается в том, что лишь немногие пытаются защитить интеллектуальную собственность, передавая клиентам заголовки C++ и двоичные файлы. Однако есть несколько (например, Numerix), которые используют эту модель, по крайней мере, несколько лет назад. Проблема с этим, конечно, в том, что вы должны поддерживать сборку для каждой возможной конфигурации клиента и не можете предоставить код шаблона. Это ограничивает вашу конкурентоспособность, как правило, гораздо больше, чем если бы ваш конкурент просто украл ваш код. - person Lance Diduck; 01.05.2010

Единственная непереносимая часть RTTI — это формат строк, возвращаемых из type_info::name().

Даже у этого есть шанс на победу, пока вы можете найти инструмент c++filt для своего компилятора, который преобразует (распутывает) такую ​​строку обратно в совместимый тип C++.

person Potatoswatter    schedule 25.04.2010

Если компилятор не «поддерживает» RTTI, означает ли это, что компилятор не может обрабатывать иерархии классов, в которых есть виртуальные функции?

Вообще все современные компиляторы C++ поддерживают RTTI... Так что забудьте об этом.

Или я неправильно понял литературу о том, что RTTI не является переносимым, а проблемы лежат в другом месте?

RTTI сегодня является переносимым и прекрасно работает на любом современном компиляторе... Однако могут возникнуть некоторые особые случаи.

На платформах ELF (Linux), когда вы загружаете библиотеки динамически (т.е. dlopen) и пытаетесь выполнить dynamic_cast к некоторому классу между библиотекой и исполняемым файлом, это может потерпеть неудачу, если вы не передадите правильные флаги для связывания исполняемого файла (-rdynamic ).

Почти любые другие случаи... Просто работает.

person Artyom    schedule 25.04.2010