![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Приветствую всех.
Александреску в 8ой главе "Фабрики объектов" пишет следующее:
Смущают выделенные аргументы в пользу неустойчивости typeid::name(). Я так понимаю, речь о том, что стандарт не даёт гарантий, но компиляторы всё-таки должны, как мне кажется, гарантировать постоянство и устойчивость работы этой функции. По-крайней мере я использую msvc++ и ничего из вышеперечисленного пока не вылезало на практике. Кто-нибудь имеет прецеденты, подтверждающие слова уважаемого автора? Это сообщение отредактировал(а) W4FhLF - 26.7.2008, 14:00 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| SaDFromSpb |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 5.4.2006 Где: Санкт-Петербург Репутация: 3 Всего: 3 |
В gcc по typeid(SomeClass).name() вылазит как правило что-то вроде KAFSomeClass1. Эти пугающие символы слева и справа от имени заставляют согласиться с автором. И вообще, если сказано, что нет гарантии, значит нет гарантии. И рассуждения "ну вроде бы по-моему должно" не к месту. Если полагаться на такие доводы, то и созданное творение "вроде бы должно будет" работать.
-------------------- "За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001) |
|||
|
||||
| W4FhLF |
|
||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Хорошо, с первым аргументом можно согласиться. Компилятор от MS возвращает "class ClassName".
Я полагаюсь на то, что вижу в дизассемблере и на то, что программа работает и ничего из описанного выше я пока не наблюдал. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||
|
|||||
| phprus |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Слова автора подтверждает страндарт. Вот:
и вот:
Следовательно эта функция ничего НЕ гарантирует и автор полностью прав.
В случае если писать под одну конкретную сборку одного конкретного компилятора, то этот подход имеет право на жизнь, однако если программа должна собираться разными версиями, возможно разных компиляторов, то такой подход неизбежно приведет к краху. Отладчик может лишь помочь найти логические ошибки. Он не увеличит вероятность угадывания того, как в компиляторе реализованы implementation-defined и unspecified требования стандарта. |
||||||||
|
|||||||||
| W4FhLF |
|
||||||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Александреску пишет:
Следовательно мы не можем использовать typeid::name() для сравнения и сортировки, если нет гарантии, что return value уникален в рамках приложения. Но стандарт это разрешает.
Гипотетические случаи возможны. На практике кто-нибудь встречал вот это:
Особенно вот это: Компиляторы ведь тоже не дураки пишут. RTTI - статические данные, интересно как они могут быть не постоянны? Только в случае, если заполняются в Run-Time какими-то служебными механизмами, которые генерируют данные по разным исходным параметрам. В exe compiled by vc++ RTTI хранится в секции .data и, следовательно, изменяться не может. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||||||
|
|||||||||
| SaDFromSpb |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 5.4.2006 Где: Санкт-Петербург Репутация: 3 Всего: 3 |
Да.. Такого не встречал. Меня тоже это смутило при прочтении... -------------------- "За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001) |
|||
|
||||
| phprus |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Нет не разрешает. У объектов этого класса есть перегруженные операторы сравнения и метод before при помощи которых можно сравнивать и сортировать объекты этих классов. Вот про что говорит стандарт. "encoded value" - это не то-же самое, что возвращает метод name(). Это даже не то-же самое, что и "pointer to a name for the type" Про то, что возвращает метод name() сказано только что его поведение зависит от компилятора и может быть практически любым.
А не кто говорит что они меняются. Но символьное имя которое возвращает name() может не иметь никакого отношения к RTTI-данным которые реально требуются программе для работы механизма RTTI.
Я сомневаюсь, что кто-то пытался использовать name() для целей в которых уникальность была-бы критична. Кстати с учетом того, что написано в стандарте даже следующая версия VС++ может начать выдавать в качестве результата метода name() вообще все что угодно. |
||||
|
|||||
| W4FhLF |
|
||||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Точно, невнимательно прочитал. Сейчас прошёлся дизассемблером, компилятор от MS, для сравнения объектов вот так:
сравниваются две строки вида: $$A6A?AVsomeclass. Когда вызывается name() возвращается только someclass.
Мне конкретно вот это интересно. Встречал кто-нибудь на практике или нет. Знаю, что в студии (2005-2008) такого произойти не может.
Может, но в этом нет логики. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||||
|
|||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
W4FhLF, такого может не быть ни в одном из существующих компиляторов, но такая возможность реализации есть, вот о ней Александреску и предупреждает. Написал это скорее всего, чтобы совсем отбить желание использоватьь name()
|
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
||||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Он ведь сказал "может не быть", а не "такого нет". -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
В плане RTTI в С++ обычно своё велосипедное решение (возможно с кодогенератором) лучше, ибо: надёжнее, функциональнее, удобнее.
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Я когда-то столкнулась с таким случаем, хотя и немного из другой оперы:
В большом приложении случайно возникают 2 класса с одинаковыми именами (в глобальном namespace). Они совершенно никак не пересекаются по файлам и вроде бы жить друг другу не мешают (все это в рамках одной большой DLL, естественно). И никто ничего не подозревает. И линкер (MSVC) все нормально собирает... А потом для одного из них начинаем использовать typeid, неважно для чего (оба класса с виртуальными функциями)... вот тут как повезет: может, сразу полезут ошибки (выполнения), и тогда ты догадаешься, куда смотреть. А может, и не сразу... Вот я повеселилась-то при отладке-то... В общем, после того случая я завела жесткую дисциплину именования классов. Кстати, насчет самостоятельных велосипедов: скажем, MFC-шному RUNTIME_CLASS, в общем-то вполне удобному несмотря на примитив - вообще накласть на все namespace'ы вместе взятые. И линкер ни фига не поможет. А вот с typeid - это все же надо чтобы очень не повезло (чтобы функций с одинаковыми сигнатурами не было ну и т.д.) - и понятно, что делать, чтобы избегать. Свое уникальное решение для каждого случая, когда нужна фабрика, изобретать - слишком хлопотно, да и тяжело потом зоопарк поддерживать. Так что лучше что-то стандартное - но аккуратно, и понимая, куда наступаешь... -------------------- ... |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 2 Всего: 261 |
W4FhLF, сейчас столкнулся с похожей проблемой определения типа. Долго рассказывать в чем суть, но. Что меня удивило. MSDN пишет, что name() - для вывода, на консоль, еще куда-ть, а для сравненй лучше использовать raw_name().
Правда, под дебагером в raw_name бред какой-то, а в name - именно тип, который мне нужен и сравнивал я рещультат name(). Проверял на структурах. Проблем не было. |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Этому есть простое объяснение. name возвращает имя типа (понятное человеку), а raw_name - некоторую уникальную строку, сопоставляемую типу. Строка, возвращаемая raw_name, обычно намного короче и потому сравнивается быстрее. |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Mal Hack, так для сравнения там есть operator==, хотя raw_name и функция operator==() скорее всего используют одни и те же данные.
Всем спасибо за ответы. В общем не всё так страшно, нужно только понимать, что ты пишешь и как оно работает, тогда всех вынеперечисленных проблем возникать недолжно. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |