Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Устойчивость std::typeinfo::name() 
:(
    Опции темы
W4FhLF
Дата 26.7.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Приветствую всех.

Александреску в 8ой главе "Фабрики объектов" пишет следующее:

Цитата

Способ, которым реализована функция type_info: -.name, позволяет применять ее лишь для 
отладки. Нет никакой гарантии, что данная строка действительно представляет собой имя 
класса
, и, что еще хуже, нет никакой гарантии, что эта строка является единственной в 
рамках приложения
. (Да, пользуясь функцией std:: type_info::name, вы можете  
получить два класса с одним и тем же именем.) И совсем убийственный аргумент: нет  
гарантии, что имя типа постоянно. Никто не может обещать, что оператор 
typeid(Line).name() вернет то же самое имя при повторном выполнении программы
. 
Живучесть реализации — важное качество фабрик, а функция std::type_info::name  
является неустойчивой. 


Смущают выделенные аргументы в пользу неустойчивости typeid::name(). Я так понимаю, речь о том, что стандарт не даёт гарантий, но компиляторы всё-таки должны, как мне кажется, гарантировать постоянство и устойчивость работы этой функции. По-крайней мере я использую msvc++ и ничего из вышеперечисленного пока не вылезало на практике. 
Кто-нибудь имеет прецеденты, подтверждающие слова уважаемого автора?

Это сообщение отредактировал(а) W4FhLF - 26.7.2008, 14:00


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
SaDFromSpb
Дата 26.7.2008, 15:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



В gcc по typeid(SomeClass).name() вылазит как правило что-то вроде KAFSomeClass1. Эти пугающие символы слева и справа от имени заставляют согласиться с автором. И вообще, если сказано, что нет гарантии, значит нет гарантии. И рассуждения "ну вроде бы по-моему должно" не к месту. Если полагаться на такие доводы, то и созданное творение "вроде бы должно будет" работать.


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
W4FhLF
Дата 26.7.2008, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(SaDFromSpb @  26.7.2008,  15:21 Найти цитируемый пост)
 Эти пугающие символы слева и справа от имени заставляют согласиться с автором.


Хорошо, с первым аргументом можно согласиться. Компилятор от MS возвращает "class ClassName".

Цитата(SaDFromSpb @  26.7.2008,  15:21 Найти цитируемый пост)
 Если полагаться на такие доводы, то и созданное творение "вроде бы должно будет" работать.


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





--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
phprus
Дата 26.7.2008, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



Цитата(W4FhLF @  26.7.2008,  13:59 Найти цитируемый пост)
Кто-нибудь имеет прецеденты, подтверждающие слова уважаемого автора?

Слова автора подтверждает страндарт.
Вот:
Цитата

The class type_info describes type information generated by the implementation. Objects of this class
effectively store a pointer to a name for the type, and an encoded value suitable for comparing two types for
equality or collating order. The names, encoding rule, and collating sequence for types are all unspecified
and may differ between programs.

и вот:
Цитата

       const char* name() const;
7 Returns: an implementation-defined NTBS.
8 Notes: The message may be a null-terminated multibyte string (17.3.2.1.3.2), suitable for conversion and
     display as a wstring (21.2, 22.2.1.5)


Следовательно эта функция ничего НЕ гарантирует и автор полностью прав.

Цитата(W4FhLF @  26.7.2008,  16:00 Найти цитируемый пост)
Я полагаюсь на то, что вижу в дизассемблере и на то, что программа работает и ничего из описанного выше я пока не наблюдал. 

В случае если писать под одну конкретную сборку одного конкретного компилятора, то этот подход имеет право на жизнь, однако если программа должна собираться разными версиями, возможно разных компиляторов, то такой подход неизбежно приведет к краху.
Отладчик может лишь помочь найти логические ошибки. Он не увеличит вероятность угадывания того, как в компиляторе реализованы implementation-defined и unspecified требования стандарта.
PM MAIL WWW ICQ   Вверх
W4FhLF
Дата 26.7.2008, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(phprus @  26.7.2008,  16:20 Найти цитируемый пост)
 an encoded value suitable for comparing two types for equality or collating order


Александреску пишет:

Цитата(W4FhLF @  26.7.2008,  13:59 Найти цитируемый пост)
нет никакой гарантии, что эта строка является единственной в 
рамках приложения.


Следовательно мы не можем использовать typeid::name() для сравнения и сортировки, если нет гарантии, что return value уникален в рамках приложения. Но стандарт это разрешает. 

Цитата(phprus @  26.7.2008,  16:20 Найти цитируемый пост)
однако если программа должна собираться разными версиями, возможно разных компиляторов, то такой подход неизбежно приведет к краху.


Гипотетические случаи возможны. На практике кто-нибудь встречал вот это:

Цитата(W4FhLF @  26.7.2008,  13:59 Найти цитируемый пост)
нет никакой гарантии, что эта строка является единственной в рамках приложения.


Особенно вот это:

Цитата(W4FhLF @  26.7.2008,  13:59 Найти цитируемый пост)
нет  гарантии, что имя типа постоянно.


Компиляторы ведь тоже не дураки пишут. RTTI - статические данные, интересно как они могут быть не постоянны? Только в случае, если заполняются в Run-Time какими-то служебными механизмами, которые генерируют данные по разным исходным параметрам. 
В exe compiled by vc++ RTTI хранится в секции .data и, следовательно, изменяться не может. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
SaDFromSpb
Дата 26.7.2008, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Цитата(W4FhLF @  26.7.2008,  16:41 Найти цитируемый пост)
Гипотетические случаи возможны. На практике кто-нибудь встречал вот это:

Цитата(W4FhLF @  26.7.2008,  13:59 Найти цитируемый пост)
нет никакой гарантии, что эта строка является единственной в рамках приложения.


Особенно вот это:

Цитата(W4FhLF @  26.7.2008,  13:59 Найти цитируемый пост)
нет  гарантии, что имя типа постоянно.


Да.. Такого не встречал. Меня тоже это смутило при прочтении... 


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
phprus
Дата 26.7.2008, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



Цитата(W4FhLF @  26.7.2008,  16:41 Найти цитируемый пост)
Следовательно мы не можем использовать typeid::name() для сравнения и сортировки, если нет гарантии, что return value уникален в рамках приложения. Но стандарт это разрешает. 

Нет не разрешает. У объектов этого класса есть перегруженные операторы сравнения и метод before при помощи которых можно сравнивать и сортировать объекты этих классов. Вот про что говорит стандарт.
"encoded value" -  это не то-же самое, что возвращает метод name(). Это даже не то-же самое, что и "pointer to a name for the type"
Про то, что возвращает метод name() сказано только что его поведение зависит от компилятора и может быть практически любым.

Цитата(W4FhLF @  26.7.2008,  16:41 Найти цитируемый пост)
RTTI - статические данные, интересно как они могут быть не постоянны?

А не кто говорит что они меняются. Но символьное имя которое возвращает name() может не иметь никакого отношения к RTTI-данным которые реально требуются программе для работы механизма RTTI.

Цитата(W4FhLF @  26.7.2008,  16:41 Найти цитируемый пост)
Гипотетические случаи возможны. На практике кто-нибудь встречал вот это:

Я сомневаюсь, что кто-то пытался использовать name() для целей в которых уникальность была-бы критична.

Кстати с учетом того, что написано в стандарте даже следующая версия VС++ может начать выдавать в качестве результата метода name() вообще все что угодно.
PM MAIL WWW ICQ   Вверх
W4FhLF
Дата 27.7.2008, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(phprus @  26.7.2008,  17:23 Найти цитируемый пост)
Нет не разрешает. У объектов этого класса есть перегруженные операторы сравнения и метод before при помощи которых можно сравнивать и сортировать объекты этих классов. Вот про что говорит стандарт.


Точно, невнимательно прочитал. 
Сейчас прошёлся дизассемблером, компилятор от MS, для сравнения объектов вот так:

Код

    someclass b(4), b1();
    std::cout << (typeid(b) == typeid(b1)) << std::endl;


сравниваются две строки вида: $$A6A?AVsomeclass. Когда вызывается name() возвращается только someclass.


Цитата(phprus @  26.7.2008,  17:23 Найти цитируемый пост)
А не кто говорит что они меняются.


Цитата

Никто не может обещать, что оператор typeid(Line).name() вернет то же самое имя при повторном выполнении программы. 


Мне конкретно вот это интересно. Встречал кто-нибудь на практике или нет. Знаю, что в студии (2005-2008) такого произойти не может.

Цитата(phprus @  26.7.2008,  17:23 Найти цитируемый пост)
 следующая версия VС++ может начать выдавать в качестве результата метода name() вообще все что угодно.


Может, но в этом нет логики. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
vinter
Дата 27.7.2008, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



W4FhLF, такого может не быть ни в одном из существующих компиляторов, но такая возможность реализации есть, вот о ней Александреску и предупреждает. Написал это скорее всего, чтобы совсем отбить желание использоватьь name()


--------------------
Мой блог
PM MAIL WWW   Вверх
UnrealMan
Дата 27.7.2008, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(vinter @  27.7.2008,  09:49 Найти цитируемый пост)
такого может не быть ни в одном из существующих компиляторов

Это вряд ли. Такой факт, скорее всего, был бы широкоизвестен.

Это сообщение отредактировал(а) UnrealMan - 27.7.2008, 14:31
PM MAIL   Вверх
W4FhLF
Дата 27.7.2008, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(UnrealMan @  27.7.2008,  12:53 Найти цитируемый пост)
Каковы ваши доказательства?


Он ведь сказал "может не быть", а не "такого нет". 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Любитель
Дата 28.7.2008, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



В плане RTTI в С++ обычно своё велосипедное решение (возможно с кодогенератором) лучше, ибо: надёжнее, функциональнее, удобнее.


--------------------
PM MAIL ICQ Skype   Вверх
Earnest
Дата 28.7.2008, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Я когда-то столкнулась с таким случаем, хотя и немного из другой оперы:
В большом приложении случайно возникают 2 класса с одинаковыми именами (в глобальном namespace).  Они совершенно никак не пересекаются по файлам и вроде бы жить друг другу не мешают (все это в рамках одной большой DLL, естественно). И никто ничего не подозревает. И линкер (MSVC) все нормально собирает... А потом для одного из них начинаем использовать typeid, неважно для чего (оба класса с виртуальными функциями)... вот тут как повезет: может, сразу полезут ошибки (выполнения), и тогда ты догадаешься, куда смотреть. А может, и не сразу... Вот я повеселилась-то при отладке-то... В общем, после того случая я завела жесткую дисциплину именования классов.
Кстати, насчет самостоятельных велосипедов: скажем, MFC-шному RUNTIME_CLASS, в общем-то вполне удобному несмотря на примитив - вообще накласть на все namespace'ы вместе взятые. И линкер ни фига не поможет. А вот с typeid - это все же надо чтобы очень не повезло (чтобы функций с одинаковыми сигнатурами не было ну и т.д.) - и понятно, что делать, чтобы избегать.
Свое уникальное решение для каждого случая, когда нужна фабрика, изобретать - слишком хлопотно, да и тяжело потом зоопарк поддерживать. Так что лучше что-то стандартное - но аккуратно, и понимая, куда наступаешь...


--------------------
...
PM   Вверх
Mal Hack
Дата 28.7.2008, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



W4FhLF, сейчас столкнулся с похожей проблемой определения типа. Долго рассказывать в чем суть, но. Что меня удивило. MSDN пишет, что name() - для вывода, на консоль, еще куда-ть, а для сравненй лучше использовать raw_name().
Правда, под дебагером в raw_name бред какой-то, а в name - именно тип, который мне нужен и сравнивал я рещультат name().

Проверял на структурах. Проблем не было.
PM ICQ   Вверх
UnrealMan
Дата 28.7.2008, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Mal Hack @  28.7.2008,  20:53 Найти цитируемый пост)
Что меня удивило. MSDN пишет, что name() - для вывода, на консоль, еще куда-ть, а для сравненй лучше использовать raw_name().

Этому есть простое объяснение. name возвращает имя типа (понятное человеку), а raw_name - некоторую уникальную строку, сопоставляемую типу. Строка, возвращаемая raw_name, обычно намного короче и потому сравнивается быстрее.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0647 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.