Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Отчего нам нужна рефлексия в C 1y

Anna | 24.06.2014 | нет комментариев

Программам нужны данные. Программы выдают лишь настоль отличный итог работы, насколько полны и валидны были входные данные. Для некоторых программ входными данными являются обыкновенные файлы либо полученная из сети информация (пример — ваш браузер). Другие программы оперируют начальными кодами. Эти вторые «мета-программы» тоже нуждаются в данных. Чем они будут добротнее — тем добротнее будет и итог.

Что же за данные мы «скармливаем» таким программам? Ну, в С больше значимым чем «что?» является вопрос «когда?» (помните Морфеуса?). Программа на С это каждого-лишь последовательность битов, которые компилятор пытается прочитать и осознать. И вот в процессе этого «понимания» компилятор преобразует код на С в машинные инструкции и (что исключительно увлекательно!) исполняет некоторую часть кода вашей программы. Да, мы говорим о мета-программировании на этапе компиляции.

Возвращаемся к вопросу «что?». Мы хотим иметь доступ ко каждому сущностям, которые только теоретически могут быть доступны на этапе компиляции: типы, члены классов, функции, доводы, пространства имён, номера строк кода, имена файлов — и всё это отлично бы иметь в «чистом виде», без каких-либо необычных препроцессорных хаков либо применения сторонних утилит. Помимо того, отлично бы получить и менее явственные вещи: информацию о конвертируемости одних типов в другие, отношениям наследования и агрегации, дружелюбных классах и функциях и т.д.

Компилятор языка С теснее имеет всю эту информацию! Но, к сожалению, не в доступной для мета-программирования форме. Получается необычная такая обстановка — мы можем исполнить кое-какой код на этапе компиляции — но вот большинства данных у нас нет. Ну и тут было бы разумно задаться вопросом «А как же мы можем эти данные получить?».

Идея лежит на поверхности и многие, наверно, удачно использовали её ранее: сделать вышеуказанные данные доступные мета-программам без требования какой-либо информации от компилятора.

Давайте посмотрим, кто у нас вообще есть. 1-й — компилятор. Вторая — метра-программа и конечный (по порядку, но не по значимости) — это программист. Ну от того что машины пока ещё не захватили мир и множество программ на сегодняшний день пишется всё-же людьми.

Данные этапа компиляции обязаны быть видимы и внятны каждому трём из них. На сегодняшний день программисты на С , несмотря на боль, пишут код в форме, больше комфортной компилятору и метапрограмме. Основными примерам являются идиома traits, библиотека type_traits и изредка — особые кодогенераторы, которые парсят код на С и «вынимают» взаимоотношения классов. Скажем, скрипт gen-meta.py из LEESAгенерирует списки типов (векторы Boost MPL) для классов, которые содержат в себе другие классы.

Когда код не автогенерируемый, мы делаем его славным для программиста применяя макросы. Многие не любят макросы из-за того, что они «прячут» код и данные, которые в сущности за ними стоят, но теперь не об этом. Есть много примеров подлинно сильных макросов: Boost SIMD, Boost MPL (когда ещё не было variadic-образцов), «разумные» перечисления, да и многое другое. Когда макросы применяются по-мудрому — они подлинно выглядят как магия. Мне довелось ощутить это при работе над библиотекой RefleX.

RefleX — это средство моделирования типов с поддержкой рефлексии на этапе компиляции для DDS Topics. Оно открытое, но вам потребоваться RTI Connext DDS, Дабы испробовать RefleX «руками». По ходу его работы происходит реформирование нативного СС типа в его представление, называемое TypeObject и маршалинг ваших данных в то, что именуется DynamicData-объект. Обратите внимание, что и TypeObject и DynamicData — сериализуемы, от того что в настоящем коде частенько бывает необходимо сберечь данные на диск либо передать по сети.

Вот пример:

// shape.h
struct ShapeType
{
std::string color;
int x;
int y;
unsigned shapesize;
};

RTI_ADAPT_STRUCT(
ShapeType,
(std::string, color, KEY)
(int, x)
(int, y)
(unsigned, shapesize))

Макрос RTI_ADAPT_STRUCT разворачивается в приблизительно 120 строк С кода, содержащего информацию о ShapeType, которая может быть использована на этапе компиляции. Он основан на макросеBOOST_FUSION_ADAPT_STRUCT. Данный макрос открывает внутренности определённого типа для библиотеки RefleX. Мета-программы на RefleX применяют эти данные для своих целей. Информация включает типы членов класса, их имена, перечисления и иную информацию.

Последние две open-source библиотеки я написал с применением этого механизма: в одной «данные» генерировались питоновским скриптом, в иной — макросами типа вышеописанных. Эти библиотеки получились дюже сильными.

Обычным шагом эволюции данной парадигмы должна стать её помощь на ярусе эталона языка. Если что-то даёт столь значительные превосходства — язык и компилятор обязаны брать на себя труд по предоставлению нужного функционала.

Всё это приводит нас к основной теме этой статьи: рефлексии на этапе компиляции. Она необходима нам. Это нужный и верный шаг эволюции языка С . Когда она будет доступна — все эти макросы и кодогенераторы будут не необходимы. У нас легко будет каждая нужная информация, там где она нужна и тогда, когда она нужна. Всё это будет трудиться стремительней, выглядеть проще и вообще быть легко сногсшибательной фичей.

Эталон С 1y обещает быть дюже увлекательным, будем следить за новостями.

 

Источник: programmingmaster.ru

 

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB