![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
начитавшись манов по разработке расширений для GCC решил: хватит с меня макросов и кодогенерации осложненной нехваткой возможностей препроцессора и информации о типах доступной на стадии препроцессирования!!!
интересует мнение форумчан: какой вы видите reflection и introspection в С/С++? и чего вам от них надо? спасибо. Это сообщение отредактировал(а) boostcoder - 24.7.2011, 16:32 |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
я как-то пытался понять что это и с чем его едят, и ничего понял Добавлено через 26 секунд попытаюсь снова.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
что-то ответов маловато.. наверное всех уже достали мои темы связанные с кодогенерацией
что мне видится необходимым: 1. генерация сериализаторов/десериализаторов. думаю использовать для этого прагмы.
в процессе написания... |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
boostcoder, плагины это конечно хорошо, но вы ведь навсегда свой проект привязываете к конеретной среде разработки. Хорошо если вам никогда не придется переписывать это на другую IDE... Но кто даст гарантию, что это вдруг когда-нибудь не понадобится? |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
я имел ввиду если нужен будет не gcc.
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Это backend для gcc. Вместо генерации кода выводит внутреннее представление в виде XML. Правда выводится далеко не все внутреннее представление, а только декларации (вроде). Для introspection/reflection должно хватить Есть еще один путь - парсить отладочную информацию (DWARF2 например) |
|||
|
||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
да. уже проверил. да. тоже проверил. и да, должно хватить. из этого:
получаем это:
многое не понятно. но члены вижу. нужно в доку посерьезней глянуть. Добавлено через 1 минуту и 9 секунд начало xml вырезал, а то форум ругался. там были только builtin функции/типы/переменные. Добавлено через 2 минуты и 35 секунд по моему, поздно что-то генерить в код, когда уже сгенерина отладочная инфа. или предлагаете двойной проход? Добавлено через 5 минут и 39 секунд и при использовании gcc-xml, выходной файл придется скармливать кодогенератору, я Вас правильно понял? при использовании плагинов же, код можно обрабатывать и генерировать тем же плагином. ну или разделить парсер и генератор на два плагина. |
||||||
|
|||||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
еще хочется интроспекции типа такой:
вроде как согласно манам, это возможно. буду пробовать. Добавлено @ 17:20 вот только нужно решить что удобней, аттрибуты или прагмы... согласно докам, обработка аттрибутов и прагм ничем не отличается. т.е. обработчики получают одинаковую инфу о контексте. Это сообщение отредактировал(а) boostcoder - 24.7.2011, 18:12 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Угу
Да
Да, это явный плюс. В принципе такой плагин можно сделать на основе того же gcc-xml, а можно и не на основе |
||||||
|
|||||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
по моему нет. gcc-xml это пропатченный gcc. т.е. и плагинами там и не пахнет. а разбирать его код ой как сложно Добавлено через 2 минуты и 19 секунд кстати дочитал до того места, где объясняется как плагины могут "общаться" между собой. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
тут, я думаю нужно получать ближайшую в скопе переменную с этим именем. или как? конечно, знание ЯП с нормальной introspection очень помогло бы в понимании... |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Я знаю их не так много (точнее совсем почти не знаю), но в Java например это сделано отдельным пакетом (java.lang.reflect). В VCL это сделано так же отдельным классом, описывающим тип. Возможно, что и тут имеет смысл сделать нечто, расширяющее RTTI. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
например что/как и что желательно получить в итоге? Добавлено через 3 минуты и 24 секунды xvr, говорю же: мне, конкретно для моей задачи необходимы два момента: 1. генерация сериализаторов/десериализаторов. 2. reflection с возможностью указать куда и как рефлектиться. т.е. - сериализатор, БД, другой объект этого же типа. но возможно в других ЯП есть более разумные и удобные моменты о которых я просто не знаю... |
|||
|
||||
| kosmonaFFFt |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Погляди в Java, там есть класс Class, описывающий классы, экземпляр которого можно получить например так:
а из него можно получить всю информацию, например методы, поля, суперклассы и т. д... -------------------- ![]() |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
|
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
осталось понять как это должно выглядеть в коде метод, или способ? тот же вопрос: как это должно выглядеть в коде? т.е. _этот_расширенный_RTTI_ - это должен быть некий тип/класс?
и снова тот же вопрос: как это должно выглядеть в коде? |
||||
|
|||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Например так:
К сожалению в С++ нету базового класса похожего на Object в Java, поэтому единственный на мой взгляд способ вернуть новый экземпляр класса, созданный через reflection - вернуть void*. -------------------- ![]() |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
тут Class это кто? какая-то встроенная сущность? а MyClass кто? и в общем, что выполняется в этой строке? |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
итак. с чем разобрался:
1. для каждой единицы трансляции формируется Abstract syntax tree. 2. реальный компилятор(cc1plus) обрабатывает только по одному файлу за раз. при передаче g++ нескольких файлов, он поочередно выполняет cc1plus для каждого файла. а значит плагин будет запускаться столько же раз, сколько файлов. 3. есть возможность навесить свой обработчик на: 1) окончание разбора единицы трансляции, 2) глобальную обработку прагм, 3) глобальную обработку атрибутов. 4. плагин может добавлять/удалять в базу стандартных прагм и атрибутов свои прагмы и атрибуты. 5. есть возможность навесить обработчик на какую-то конкретную прагму или атрибут. т.е. сначала регаем имя, потом вешаем свой обработчик на реганное имя. 6. нет возможности навесить обработчик на разбор деклараций :( хотя в инете есть патч для этого. 7. нет возможности влиять на синтаксис языка. 8. AST можно генерить/изменять/удалять. т.е. при изменении AST можно с кодом сделать все что угодно. далее... Это сообщение отредактировал(а) boostcoder - 26.7.2011, 09:47 |
|||
|
||||
| EnergoHokum |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 600 Регистрация: 10.11.2006 Где: Россия, Ставропол ь Репутация: нет Всего: 6 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
условно : Class - type_info MyClass - struct MyClass MyClass.class - typeid(MyClass) но применительно не для всех типов, а только для полиморфных.. что позволяет после создания объекта имея ссылку на класс динамически кастовать его к нужному интерфейсу.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
EnergoHokum, нет нужды
mes, а можете показать то же самое ,но в виде примера на с++? ;) т.е. каким вы видите использование, и какие дополнительные возможности должен предоставлять этот самый расширенный type_info? Добавлено через 1 минуту и да, type_info и typeid() никогда не использовал |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
это я к тому, что не очень представляю для чего они нужны, и как их использовать. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
не понимаю...
Добавлено через 6 минут и 52 секунды mes, т.е. смысл в том, чтоб объект мог создать объект своего же типа? а как это можно использовать? еще не понял что Вы хотели продемонстрировать с помощью dynamic_cast? |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
нет в том, что объектом не является не только инстанция класса, но и сам класс.. какими возможностями будет обладать объект-класс зависит от идеологии.. в рантайме мы можем создать только безличностный объект, а dynamic_cast показываеткак привести к нужному интерфейсу Добавлено через 1 минуту и 39 секунд мой пример был приведен не по теме, а как ответ на Добавлено через 5 минут и 37 секунд если ближе к теме, то кусок должен выглядить так :
Добавлено через 7 минут и 50 секунд P.S. и вместо type по смыслу больше подходит Class.. |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
все равно не понял.. можете как-то псевдокодом показать пример того как это дело можно использовать... и для чего? ;) Добавлено через 3 минуты и 52 секунды я не понимаю я этого, наверное потому что никогда не писал на ЯП которые это умеют делать |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Вешать сюда. По AST со входа нужно генерить таблицы с расширенным RTTI (RTTIEx), и специальный сегмент для общей таблицы с именами типов и ссылками на RTTIEx для каждого типа. Это вторая часть reflection - специальная библиотека. Этот Class использует таблицы RTTIEx для выдачи энумераторов на все member'ы класса. Каждый экземпляр Class описывает один конкретный тип Кроме энумераторов Class должен содержать функции для чтения/записи/вызова member'ов исходного класса и функцию для создания этих самых исходных классов. Конкретные интерфейсы написать прямо тут затрудняюсь - их слишком много |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
тут type - какой-то базовый тип? т.е. таким образом мы можем получить объект базового типа который умеет создавать объекты типа "A" ? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
таким образом мы получаем объект (объект-тип), который знает "все" о классе типа "А" , а также может создатьинстанцию этого класса.. P.S. к базовым классам типа A отношение не имеет, это отдельная линия.. |
|||
|
||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
но в таком случае, дополнительный код будет генериться для всех классовых типов. разве это нужно? я представлял что прогер сам помечает класс при помощи прагм или атрибутов. и для этих типов и будет генериться все необходимое..
очень желательно это объяснить в боооолее развернутой форме. ибо я никогда не разрабатывал/модифицировал компиляторы. и мне еще многое не понятно с этим понятно. вроде...
тоже понятно...
чьи интерфейсы? |
||||||
|
|||||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Добавлено @ 11:22 вот еще пример
Это сообщение отредактировал(а) mes - 26.7.2011, 11:48 |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, минутку... это нужно переварить..
Это сообщение отредактировал(а) boostcoder - 26.7.2011, 13:17 |
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
к примеру, если имя типа/объекта известны во время компиляции в виде строки, то как создать объект или получить ссылку на существующий объект - понятно.
тут все просто. но для того чтоб интроспекция была динамической, нам нужно уметь выполнять все тоже самое но в рантайме... а для этого кодогенерация в компайлтайме не подходит... т.е., все классовые типы должны наследовать базовый тип Class, к примеру...
Это сообщение отредактировал(а) boostcoder - 26.7.2011, 13:24 |
||||
|
|||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
т.е. к примеру такая программа:
должна быть оттранслирована в нечто типа этого:
правильно? еще не понятно, как быть с объектами... create и invoke должны возвращать указатели? и еще, будет ли такой код считаться логичным, и нужно ли оно вообще?
Это сообщение отредактировал(а) boostcoder - 26.7.2011, 18:07 |
||||||
|
|||||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Чтобы это сделать, нужно при компиляции сгенерировать код, который для каждого класса в программе при ее запуске создаст объект типа Class (или type_info или как-нибуть еще) и положит его в какую-нибудь коллекцию (например в Java этим занимается ClassLoader виртуальной машины), чтобы можно было потом его в это коллекции найти, извлечь и использовать... Классы в программе не должны наследоваться от класса Class, для каждого класса должен быть создан объект класса Class, но желательно иметь что-то типа класса Object, от которого они бы наследовались... Ну или как-то так... З.Ы. Все это взято мной из воспоминаний о том, как работает reflection в Java... -------------------- ![]() |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
т.е. получается, что все объекты типа Class ссылаются на какую-то глобальную карту. и данные для этой карты нужно генерировать в компайлтайм. а инициализировать в рантайм? правильно мыслю?
Добавлено через 1 минуту и 36 секунд kosmonaFFFt, можешь показать тоже самое в коде? или в псевдокоде. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
все объекты, как принимаемые аргументы, так и возвращаемые, в том числе Void являются наследником Object.. просьба не путать типы Object и Class.. если первый является базой для всех полиморфных типов, то второй метаинформация о классе.. т.е. Class это такой объект с помощью которого можно создать наследника Object.. Добавлено через 2 минуты и 14 секунд я приводил примеры по динамическому, потому как в статике и так все типы известны и никаких доп. ухищрений не надо.. |
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
о! понял mes, а по остальным вопросам что-нибудь ответите? ;) Добавлено через 1 минуту и 14 секунд еще нужно решить что нужно в интерфейсах Class и Object... и этот момент мне все еще не понятен -
|
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
все принимают и возвращают объекты, а Void :
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Class "умееет" создавать объект, знает его размер, может выдать енумерацию полей и функци, а возможно даже прикрепить нужную функцию..
|
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, я себе это представлял так:
Добавлено через 14 минут и 11 секунд еще не уверен что нужны все эти типы:
может нужен только Value у которого должны быть методы для каста его внутреннего значения в нужный тип? Это сообщение отредактировал(а) boostcoder - 26.7.2011, 16:29 |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Class не состоит в иерархии Object`а.. грубо говоря он служит посредником между строковым именем и созданием объекта...
|
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
2 boostcoder: попробуйте представить часть описания типов из AST в виде иерархии классов - это и будет основа для интроспекции в RTTIEx (a-la Class, точнее его энумераторы)
Когда это более менее устаканится, можно будет переходить к проектированию 2й части интерфейсов Class'а - операции по модификации/вызовам через эти энумераторы А уж к 3й части - созданию объектов, можно будет переходить когда первые 2 будут готовы. Иначе у вас получится знатная каша, а не reflection |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Я не знаю спецификацию AST из gcc поэтому точно написать не смогу. Но в общей форме, это должно быть как то так
В общем все эти классы представляют один узел в AST. Для доступа к атрибутам узла и потомкам узла в AST используются методы этих классов Методы Member::put_data/Member::get_data/Member::call_method используются для 2го уровня - манипуляция с member'ами объекта по имени Кстати, одной интроспекции недостаточно для стриминга произвольных классов. Стримить указатели, базируясь только на их типах увы не получится - проблемы распределения памяти под данные все равно придется решать вручную |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
xvr, спасибо. сначала попробую реализовать идею в терминах возможностей с++. а тогда уже и видно будет, что есть, а чего не хватает..
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
тут TypeKind - enum? Добавлено через 12 минут и 22 секунды xvr, еще типа Object не хватает? или так задумано? |
|||
|
||||
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Если wishlist ещё открыт, то могу предложить автогенерацию оператора == по указанным полям.
(как-то не очень понятно получается... щаз попробую на примере)
эта pragma (не обязательно pragma... можно что угодно ) должна сгенерить след. код
если же эта прагма стоит внутри структуры/класса, то должен генериться оператор == с одним параметром -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Да
В других языках этот класс автоматически становится в предки любому классу. В С++ такого класса нет, и собственно интроспекция не требует его наличия. |
||||
|
|||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
mes, спасибо. Вы последний комментарий читали (от юзера garex) ?
Да и не хочется таскать boost только ради этого... плюс к тому скорость этого метода (там же в комментариях замеряли) раза в полтора (!!!) ниже. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
borisbn, принято. это будет самая простая задача
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ссылку дал, как информацию к размышлению, не более Это сообщение отредактировал(а) mes - 27.7.2011, 11:30 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
xvr, поясните пожалуйста следующие моменты ;) а то в роде и понимаю, а вроде и нет..
Up. понял get_size() - это sizeof(type) get_align() - это выравнивание get_shift() - смещение Это сообщение отредактировал(а) boostcoder - 27.7.2011, 20:55 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
эм.. вопрос: метаинформацию генерить для всех типов в единице трансляции?
и еще один: при компиляции нужно собирать метаинформацию о типах. где ее сохранять? идея первая - в генерить статический_константный_массив. но проблема в том, что типов может быть тысячи ,что вызовет переполнение стека. идея вторая - генерировать только инициализатор для массива. а при старте программы выделять память в куче и инициализировать ее. для этого в AST находим функцию main() и в нее иньектим init() который это проделает. выскажитесь кто-нибудь ;) Это сообщение отредактировал(а) boostcoder - 27.7.2011, 14:50 |
|||
|
||||
| Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
а помечалка не устанет? в смысле, это как-то не логично, писать reflection и заставлять юзера помечать классы... Это сообщение отредактировал(а) boostcoder - 27.7.2011, 17:14 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
на данный момент разобрался со сбором инфы из AST.
1. итерироваться от глобального неймспейса по всем вложенным с неограниченным уровнем вложенности. 2. перечислять все декларации в любом из неймспейсов. 3. определить/фильтровать типы деклараций. 4. перечислять члены и вложенные декларации структур/классов с неограниченным уровнем вложенности. 5. добавлять/изменять AST. вроде все что нужно... пока что не нашел функцию, которая из строкового представления декларации генерит AST. потому как создавать AST "руками" это жесть Это сообщение отредактировал(а) boostcoder - 28.7.2011, 08:33 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Это должно настраиваться (через опции командной строки). Либо все, либо специально помеченные (и унаследованные от них)
угу, стек не переполнится - статические массивы помещаются не в стеке. Посмотрите, как генерятся RTTI таблицы, и постройте там же Простые массивы с константами тоже сложно сгенерить? Все PODы и по одной штуке на каждую разновидность неPODов - функция, структура, массив, класс, и т.д. и т.п. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
кстати вариант. при том, это возможно.
ы. а где? это где смотреть? сложно - понятие относительное. я вообще-то предполагаю, что должна быть функция генерящая AST из ("int i = 0;"). но пока что я ее не нашел. это понятно. дело в том, что массив в gcc тоже под... попробую отыскать возможность получить больше информации о ноде... Добавлено через 45 секунд в моем понимании, не_POD - это все что содержит функции-члены. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
в области данных Добавлено через 8 минут и 17 секунд а почему этот не_POD один, а каких тогда POD`ов много ? раз уже подошли вплотную к AST, мож и POD'ам уделить внимание, чтоб не вводить в заблуждение хотя бы самого себя.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
это как? по правде сказать, всегда старался избегать использования статических переменных.. прошу прощения, запутался... по поводу POD`ов создам лучше отдельную тему. чтоб эту не хламить.. да-да-да. создаю тему. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
кстати, разобрался как итерироваться по узлам-предкам Это сообщение отредактировал(а) boostcoder - 28.7.2011, 01:31 |
|||
|
||||
| kosmonaFFFt |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Псевдокод:
Тут я вижу 2 варианта - либо вставить код инициализации объектов Class в начало main(), либо сразу сгенерировать во время компиляции и поместить в секцию данных программы, или куда там статические данные идут... Главное, чтобы global_classes из примера выше был доступен в рантайме... Можно для начала просто попробовать C++ код сгенерировать, примерно как в Qt с их QMetaObject... И да, если я что-то где-то не очень понятно объясняю, то это потому, что для меня основными языками являются Java и C#, и к наличию reflection я привыкший... -------------------- ![]() |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
6. итерироваться по списку аргументов со всеми вытекающими.
7. определить что поддерево является декларацией шаблона. 8. определить что поддерево является статической_переменной/статической_функцией/статическим_членом. Добавлено @ 08:09 kosmonaFFFt, понял. все же лучше использовать глобальный_статический_константный_объект. Это сообщение отредактировал(а) boostcoder - 28.7.2011, 08:33 |
|||
|
||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Ну да, тоже вариант... -------------------- ![]() |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Угу, только не объект (в понимании С++), а просто таблицы. Т.е. глобальный массив констант. Код, генерируемый gcc для RTTIEx не должен содержать исполняемого кода (т.е. неиспользуемая RTTIEx не должна вызывать накладных расходов run-time) Яркий пример - уже упомянутые мною таблицы RTTI (смотреть в генерируемом ассемблере и в сорцах gcc), и таблицы для поддержки эксепшенов |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
Вы меня переоцениваете Добавлено через 2 минуты и 33 секунды понятно. |
|||
|
||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
ИМХО не обязательно, можно сделать что-то типа class-loader'а, который бы в рантайме по мере использования классов создавал бы нужную информацию... Хотя это уже будет не С++... -------------------- ![]() |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
не нужно рантайм нагружать тем, что можно сделать и без него. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
а почему не ложить в вектор указатели на void? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
потярел нить, откуда появился этот код, но полагаю, потому что void * в отличии any не копиэйбл, а также не известно как его удалять.. |
|||
|
||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
еще несколько вопросов.
как я понимаю, RTTIEX должен быть таким:
где type - enum. так? тогда вопрос: enum нужно генерить для всех типов в единице трансляции? Добавлено через 1 минуту и 56 секунд
не понял... кот от xvr`а:
|
||||||
|
|||||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Можно. А еще можно посмотреть интерфейсы в java.lang.reflection и скопировать идеи оттуда (насколько это будет возможно) В принципе можно. Но тогда на вызывающей стороне придется создавать все параметры в виде явных переменных и брать на них указатели. Кроме того, передавая значения в некой обвертке (AnyValue) можно существенно упростить жизнь вызывающей стороне, если дать возможность объекту Class проводить неявные преобразования аргументов. Например - если функция принимает параметр целочисленного типа, то вызывающая сторона может задать нечто типа long long и не вдаваться в подробности о конкретных размерах аргумента. Типа такого. Для составных типов (структур, классов, массивов, функций и т.п.) тут еще должны присутствовать такие же записи для всех вложенных элементах (поля структур, аргументы функций и пр)
Не enum'ы а инстансы rtti_ex_. Да, для всех. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
я ж не знал понял. ага. не понял... |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
xvr, меня тут мысль посетила...
вот AST генерится на основании кода единицы трансляции. значит в нем(в AST) все связанно. а если я в этот AST добавлю свой подAST, то, прежний AST по идее станет незаконченным/неправильным/испорченным. так? |
|||
|
||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Ну это думаю смотря как добавлять... AST это просто дерево, построенное из исходников, на основе которого генерируется промежуточный или машинный код, так что по сути эффект добавления чего-то в AST может быть эквивалентен эффекту добавления чего-то в исходники перед компиляцией... -------------------- ![]() |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Главное изменить AST до прохода всяческих оптимизаций, тогда вероятность ошибок уменьшится...
А вообще на тему компиляции могу посоветовать почитать что-то типа этого: http://www.proklondike.com/books/thobshee/compiler2.html -------------------- ![]() |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
я его и изменяю сразу после построения. еще вопрос. допустим юзер хочет создать объект в неймспейсе:
как быть? получается что таблицу типов нужно генерить не в виде простого массива.. это должен быть массив cons`ов ? я правильно мыслю? |
|||
|
||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
По одной штуке rtti_ex_ на каждый тип Я уже где то писал вверху - таблиц должно быть 2 штуки (точнее 2 набора таблиц) - 1 набор с RTTIEx (rtti_ex_) на каждый тип (извлекаются по уникальному имени, приблизительно таким же, как таблица для обычного RTTI). А вторая таблица - общая для всей программы. В нее складываются имена типов классов и адреса в 1ю таблицу RTTIEx. Вторая таблица должна генерироваться в отдельной секции объектного файла, что бы линкер смог собрать ее из отдельных единиц трансляции (как он собирает вызовы конструкторов и деструкторов статических экземпляров объектов и таблицу для обработки исключений) Вот пример:
А вот он же, но с демангленными именами:
|
||||||
|
|||||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
понял! буду усваивать. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Строка 81 - таблица RTTI для класса A помещена в отдельную секцию (строка 82,86) с уникальным именем с пометкой для линкера (строка 83,88) оставить только 1 экземпляр этой секции. Причем отдельно размещены имя класса и собственно таблица typeinfo
В строке 93 в специальной секции помещается таблица для обработчика эксепшенов. Линкер соберет все такие секции со всей программы в 1 массив (секцию) Кстати, мне тут пришла в голову мысль - стриминг данных, базирующийся на интроспекции конечно вещь весьма универсальная, но увы не очень эффективная. Т.к. в процессе работы программы будет по сути происходить интерпретация типов данных. Гораздо более эффективным был бы стримминг, для которого был бы сгенерирован готовый код на этапе трансляции. К сожалению это нельзя сделать универсальным способом, т.к. способ записи/чтения бинарного (или текстового) потока (а так же его структура) сильно зависят от приложения. Да и сам стриминг так же не может быть целиком описан только типами данных. Так что тут напрашивается некий генератор функций/классов для стриминга (видимо по некоторым, заданным пользователем шаблонам). У меня пока нет ясного видения как это спроектировать |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
xvr, спасибо. разбираюсь
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
"отправление" данных в поток (stream) , или грубо говоря сериализация.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
после того как разобрался с получением информации, интересна стала не только сериализация(reflection), но и нормальная introspection. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
reflection/отражение:
introspection:
вроде как я все правильно понимаю.. да и не в этом суть. xvr меня озадачил ассемблерным кодом и всем сопутствующим... конечно, если бы кто-то ткнул в ссылку или пример, все было бы сильно проще |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
на идею не забил. просто сейчас по теме больше общаюсь на stackoverflow и в списке рассылке gnu-gcc. вроде как есть надежда понять всю эту магию.
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
в общем, ковыряниями/тыканиями/читаниями, ничего не получается. доки мало. почти нет.
пришел к решению, дважды обрабатывать единицу трансляции. первый раз - для сбора инфы, второй - для компиляции. и того, процесс получится таким: 1. запускаем компилятор+плагин для сбора информации. 2. плагин из исходного файла и собранной информации генерит временный файл и завершает компилятор. 3. компилим временный файл как обычно. вроде все логично... Добавлено через 1 минуту и 28 секунд xvr, скажите, а секция данных, может быть любого размера? есть хоть какие-то ограничения? |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Отдельно взятая секция не может превосходить размера адресного пространства (т.е. 4G на 32bit приложении). Форматы файлов (elf/PE) могут налагать дополнительные ограничения. Но скорее всего гораздо быстрее сломается компилятор/линкер/да и сама программа в run-time. Но в любом случае размеры любых секций до десятков мегабайт должны восприниматься без особых проблем |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
давайте попытаемся сэмитировать необходимое поведение/реализацию, как будто для этого достаточно только языковых средств.
такой код:
http://liveworkspace.org/code/8aae0e0cfb55...28c20b3ceadf96f начиная с 86ой строки, я пытался сэмитировать поведение. возникло два вопроса: 1. член offset, структуры rtti_ex_, каково должно быть его значение для типов самого верхнего уровня? т.е. тех, что не являются чьими-то членами. 2. по идее, rtti_ex_, должен содержать массив типов member_type_ ? или же, rtti_ex_ должны ссылаться на другие rtti_ex_, и тип member_type_ вообще лишний? Добавлено @ 17:55 еще непонятно как быть при декларации данных-членов, и декларации типов-членов, как например "name2::name3" Добавлено через 13 минут и 2 секунды по идее, в "enum type_" нужно добавить член decl_, который будет указывать на то, что элемент rtti_ex_ описывает декларацию структуры(или что еще попадает под декларации? typedef?). Это сообщение отредактировал(а) boostcoder - 1.10.2011, 17:56 |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Ну например -1
И rtti_ex_ и member_type_ внутренние структуры, которые собственно и должен генерить компилятор. Пользователь должен работать только с функциональным интерфейсом (class_ и member_), и не иметь доступа к внутренней реализации. Что касается массивов member_type_ в rtti_ex_, то да, там должен быть указатель на массив member'ов (для структур/классов). И в принципе member_type_ действительно может отсутствовать, т.к. сейчас он полностью перекрывается с rtti_ex_. В принципе member_type_ должен содержать поле offset, имя и ссылку на rtti_ex_. rtti_ex_ не должен содержать offset.
Для них ввести специальные сущности в enum class type_ rtti_ex_ должен описывать тип, а member_type_ - инстанс (переменную верхнего уровня, или поле в структуре (типе)) |
||||
|
|||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
ага. понял.
действительно.
ок. |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
xvr, скажите, а как быть с повторами элементов глобального массива rtti_ex_? получится так, что для каждой единицы трансляции будет сгенерен такой массив. ведь элементы в таких массивах будут в большинстве своем повторяться. я понимаю(вроде как) что код использующий массив типов rtti_ex_ этой единицы трансляции будет знать только об этом массиве, и никакие перекрестные ссылки не будут иметь место. но все же, насколько это логично, и правильно ли я размышляю?
|
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Надо бороться
Угу. Я уже приводил пример, как с этим борются в GCC - массив создается только на этапе линковки (линкером) из содержимого специальной секции. Каждый экземпляр rtti_ex_ помещается в отдельную именованную (именем замангленного типа) виртуальную секцию, и линкер на этапе линковки выкидывает дублирующиеся элементы, а все, что осталось, помещает в массив (точнее в отдельную секцию - в GCC доступ к экземплярам rtti производится по метке с именем, а не по индексу в массиве). |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
отменяется. разобрался с модификацией AST из плагина. есть возможность генерить что угодно. нарукоблудил несколько кодов декларации переменных/структур/функций/методов. никаких особых сложностей нет. все даже проще чем я ожидал и, оказалось, что при модификации/добавлении чего-либо в AST, оно не "портиться"(о чем я переживал), и последующие алгоритмы обработки AST схватывают абсолютно все что в нем. ведь в плагин, AST передается сразу после разбора единицы трансляции. т.е. никакие алгоритмы/оптимизаторы еще не отработали. Это сообщение отредактировал(а) boostcoder - 5.10.2011, 01:18 |
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
итак. давайте начнем с простого.
создадим библиотечный код, который позволит программе использующей его, скомпилиться. даже если к единице трансляции не был применен плагин.
использоваться это дело будет так:
тут, для create(), мне нужно изменить строку на такую: "new type;" если же конструктор типа требует аргументы - заменяем так: "new type(arg1, arg2, ...);" clone. тут мне нужно определить тип на который указывает аргумент, и сформировать такую строку: "new type(*t1);" пока все верно? Это сообщение отредактировал(а) boostcoder - 6.10.2011, 08:56 |
||||
|
|||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Угу
Так, но есть одно 'но' - как задать аргументы? reflectpp::create должен иметь фиксированную сигнатуру, т.е. аргументы придется передавать массивом чего то типа VARIANT. Передавать через ... не вариант - это потребует знать тип и количество аргументов статически в момент вызова reflectpp::create, что сводит на нет всю идею рефлексии
Угу |
||||||
|
|||||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
xvr, я тут вот что подумал..
для создания объектов произвольного типа, в структуру rtti_ex_ нужно добавить метод(указатель на функцию?) create(). так ведь? ну и free(), за одно. т.е. что-то типа этого:
верно мыслю? |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| boostcoder |
|
||||||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
опишу заново свое видение всего этого добра, чтоб расставить точки где надо.
1. функция create(). возможные варианты использования:
карта типов нужна для:
т.е. нужна карта типа такой:
где ключ - хеш сумма от имени, значение - указатель на объект. и еще одна типа такой:
где ключ - указатель на объект, значение - указатель на rtti_ex_ этого типа. по идее, нужна еще и третья карта, позволяющая создавать объекты типа class_ по имени типа. еще один пример:
мне не нравится присутствие трех карт. какие предложения по этому поводу? Это сообщение отредактировал(а) boostcoder - 6.10.2011, 16:11 |
||||||||||
|
|||||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
во первых почему создавать, во вторых зачем Вам столько карт ? во вторых Вы собрали в одну лукошко разные по сути и природе явления.. Это сообщение отредактировал(а) mes - 6.10.2011, 16:17 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, Ваши предложения?
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
и так есть у вас _тип_ зная его Вы можете как создать объект, так и удалить его..
_тип_ у Вас создается при запуске программы и держится до конца.. Вам нужно не создавать, а получать.. хранить ли ассоциацию картой или сделать просто список _типов_, или список таблиц _типов_ зависит от вашей концепции.. трудно сказать, потому что концепция к которой Вы стремитесь не до конца ясна.. прежде всего rtti_ex предназначена для любых типов или только для классовых ? если для всех, то вопрос, для чего может понадобиться создание объекта неполиморфного класса по имени ?! Это сообщение отредактировал(а) mes - 6.10.2011, 16:26 |
|||
|
||||
| boostcoder |
|
||||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
для всех.
по простому - юзер будет в терминале вводить имя. или же так:
или так:
Это сообщение отредактировал(а) boostcoder - 6.10.2011, 16:42 |
||||||||
|
|||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ну создал юзер тип int как void * и что делать с ним дальше ? если Вы о том что в яве и шарпе можно создавать интегральные типы, так только те что являются по сути объектами.. т.е. только полиморфные типы.. можно конечно преврать и простые типы в полиморфные посредством например интектуального указателя.. но опять напрашивается вопрос, что за модель у нас в конце тунеля ? или просто попытка набросать побольше фичей, без учета возможностей их иоспользования ? Добавлено через 2 минуты и 39 секунд |
|||
|
||||
| Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
я тоже противник ограничений, но давать юзеру пол-лопатки и дырявое ведерко, для меня не что иное как издевательство Это сообщение отредактировал(а) mes - 6.10.2011, 21:26 |
|||
|
||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Может не reflectcpp::create("obj_name = type1"), а reflectcpp::create("type1", "obj_name")? И еще мое мнение - раз уж это для C++, не лучше ли будет использовать вместо char* нормальный std::string и классы вместо структур с функциями? -------------------- ![]() |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
структура с функциями это тот же класс.. иногда удобнее, потому что по умолчанию public.. |
|||
|
||||
| boostcoder |
|
||||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, что конкретно Вы хотите сказать? без намеков, пожалуйста.
тут есть некоторая неопределенность.
отметки 1 и 2. т.е. вторым аргументом может быть как имя объекта, так и аргумент в конструктор объекта. хотя я склоняюсь к тому, чтоб обязать юзера паковать аргументы в класс-обертку, например такой: http://liveworkspace.org/code/7f3184c1c270...a6f850de238eccb
Добавлено через 6 минут и 19 секунд т.е. использоваться это будет как-то так:
Это сообщение отредактировал(а) boostcoder - 7.10.2011, 10:13 |
||||||||
|
|||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ну вот возьмем Ваш последний пример.. зачем тогда нужна вся rtti_ex, если в конечном счете никакой безопасности при передачи аргументов ? если хотите динамическую типизацию, так делайте ее, если достаточно небезопасного инвокинга - делайте его, но не надо смешивать различные подходы в один соус.. Это сообщение отредактировал(а) mes - 7.10.2011, 11:12 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
не связываете объекты с рантайм информацией.. Добавлено через 2 минуты так объсните что я могу делать с void* , если тип задан в рантайме.. Добавлено через 4 минуты и 48 секунд Вы оглядываетесь на языки (ява, шарп и т.д.) и думаете почему в них есть рефлексия и все плюшки для простых типов, а Вам на С++ нельзя... так ? так в тех языках, эти простые типы далеко не так просты, и каждый является объектом.. т.е. (как минимум) имеет ссылку на тип, к которому он принадлежит.. а так же существует целый ряд правил, о совместимости этих типов.. Добавлено через 8 минут и 15 секунд кстати c++/cli (для .net) тоже умеет многое из названного, но зато какими жертвами.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
+ = Ваши предложения? |
|||
|
||||
| kosmonaFFFt |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Я тут подумал, и, по моему, регистрация уже созданных объектов в ком-нибудь словаре по имени немного из другой области - обычно такая функциональность встречается в IOC контейнерах и к reflection отношения имеет мало, например в Java и C# в reflection такого нет... Передача параметров в виде "obj_name = type1" тоже на мой взгляд неудачна, т. к. во первых придется писать парсер выражений, а во вторых нарушается статичекая типизация C++... Если и делать регистрацию объектов в контейнере, то лучше отдельным методом...
Я имел в виду, что не лучше ли сделать вместо структуры rtti_ex и функций по работе с ней класс, например RttiEx, получать объект этого класса для типа и работать дальше с ними... Примерно так:
Соответственно классы RttiEx, Field, Method из вышеприведенного примера будут реализованы в reflection-библиотеке и предоставлять универсальный механизм для работы с объектами и классами в рантайме... Это сообщение отредактировал(а) kosmonaFFFt - 7.10.2011, 13:51 -------------------- ![]() |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
mes, reflectpp::create() используется только в с++ коде. это библиотечная реализация.
далее, в той самой функции(которую будет создавать компилятор) которая создает объект одного типа, я буду генерить каст из указателей на void в нужный тип. и после этого передавать в конструктор. если Вы об этом. Добавлено @ 14:01 это нужно для binding`а с++ кода с run-time скриптом. т.е. скрипт может обращаться к объектам созданным не им только в том случае, если эти объекты зареганы в мапе. сам же скрипт, будет регать все объекты которые создает. это меньшее о чем я беспокоюсь. так в том то и смысл. нет. rtti_ex_ - это внутренние структуры. они используются только внутрях всего этого дела. юзер же работает с class_ и member_. смотрите: http://liveworkspace.org/code/f6f7dc0eb32d...a001570e37d93ec Добавлено @ 14:01 rtti_ex_ у юзера не будет. будут class_ и member_. Это сообщение отредактировал(а) boostcoder - 7.10.2011, 14:04 |
|||
|
||||
| mes |
|
||||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
только вот не компилится.. Добавлено через 1 минуту и 52 секунды ну да ладно..
и зачем в динамическом методе нам шаблон ?! Добавлено через 4 минуты и 52 секунды
ну вот например связка : http://liveworkspace.org/code/5b558ca8d6b8...4616b3222f3422d гарантирующая правильное создание удаление, и дополняется возможностью проверки совместимости типов.. ну и создание по имени то же не за горами |
||||||||||
|
|||||||||||
| kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Извините за немного оффтоп... Вам рефлекшн нужен только для скриптинга? Просто по моему рефлекш к скриптингу имеет мало отношения, просто он может при этом использоваться, а может и не использоваться... -------------------- ![]() |
|||
|
||||
| boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
lда. недописал, ибо некоторые моменты не ясны. собственно этим и занимаюсь. его там не будет. по идее, там будет args_pack.
осмыслить нужно... Добавлено через 2 минуты и 41 секунду нет. это предполагаемая финальная возможность. основная же цель - привнести в с++ расширенную информацию о типах, плюс, динамические плюшки для операций с типами. Добавлено через 11 минут и 16 секунд
понял. о чем-то подобном я писал выше. но я предполагал что rtti_ex_ должен содержать в себе указатели на функции, которые плагин будет генерить для каждого типа. и при инициализации глобального массива rtti_ex_ привязывать каждый элемент к своим функциям. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
суть не в том, где и когда размещать таблицу функций, а в том, что каждый объект должен иметь указатель на свой тип, поэтому void* для передачи отменяется.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
ааа, ну да т.е. каждый пользовательский тип нужно оборачивать во что-то типа object_t? Это сообщение отредактировал(а) boostcoder - 7.10.2011, 14:53 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
или я "того", или сегодня не мой день не затруднит ли Вас объяснить на пальцах задумку? а то есть подозрение, что я все же чего-то недопонимаю... Это сообщение отредактировал(а) boostcoder - 7.10.2011, 14:59 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
первый случай не безопасный, второй вполне safe_cast для чистого void* применить не получиться .. Добавлено через 12 минут и 40 секунд вот добавил созданиепо строковому имени : http://liveworkspace.org/code/d6ab67485b64...34102089de2a7bd Это сообщение отредактировал(а) mes - 7.10.2011, 15:21 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот добавил примитивный инвокинг : http://liveworkspace.org/code/3821cf66d30d...a6d63c1cc5a270c
расширить для произвольного кол-ва аргументов проблем не составляет.. проблематично продумать правила конвертации и проверки совместимости типов.. Это сообщение отредактировал(а) mes - 7.10.2011, 16:15 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
разбираюсь.
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот еще один примерчик для разбора, как раз посвящен проблеме конвертации типов..
если продумать правила можно будет это дело автоматизировать : http://liveworkspace.org/code/e40598e4dfb1...6d347046968ad29 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |