Это началось как вопрос SO, но я понял, что это довольно нетрадиционно и, исходя из фактического описания на веб-сайтах, он может быть более подходящим для программистов. Так как вопрос имеет большой концептуальный вес.
Я изучал clang LibTooling, и это очень мощный инструмент, способный разоблачить весь «мелкий элемент» кода дружественным образом, то есть семантическим способом, а не угадывая. Если clang может скомпилировать ваш код, то clang уверен в семантике каждого символа внутри этого кода.
Теперь позвольте мне сделать шаг назад.
Есть много практических проблем, которые возникают, когда кто-то участвует в метапрограммировании шаблонов C ++ (и особенно, когда выходит за рамки шаблонов на территорию умных, хотя и пугающих макросов). Честно говоря, для многих программистов, в том числе и для меня, многие из обычного использования шаблонов также несколько пугают.
Я думаю, хорошим примером были бы строки времени компиляции . Это вопрос, которому уже более года, но ясно, что C ++ на данный момент не делает это простым для простых смертных. Хотя просмотра этих вариантов недостаточно для того, чтобы вызвать у меня тошноту, тем не менее, я не уверен в том, что смогу создать волшебный, максимально эффективный машинный код, который бы подходил для любого модного приложения для моего программного обеспечения.
Я имею в виду, давайте посмотрим правде в глаза, люди, строки довольно простые и простые. Некоторым из нас просто нужен удобный способ испускания машинного кода, в котором определенные строки «запекаются» значительно больше, чем мы получаем при прямом кодировании. В нашем C ++ коде.
Введите clang и LibTooling, которые предоставляют абстрактное синтаксическое дерево (AST) исходного кода и позволяют простому пользовательскому приложению C ++ правильно и надежно манипулировать необработанным исходным кодом (используя Rewriter
) вместе с богатой семантической объектно-ориентированной моделью всего в AST. Это обрабатывает много вещей. Он знает о расширениях макросов и позволяет вам следовать этим цепочкам. Да, я говорю о преобразовании исходного кода в исходный код или переводе.
Мой основной тезис здесь заключается в том, что clang теперь позволяет нам создавать исполняемые файлы, которые сами могут функционировать как идеальные пользовательские этапы препроцессора для нашего программного обеспечения C ++, и мы можем реализовать эти этапы метапрограммирования с помощью C ++. Мы просто ограничены тем фактом, что этот этап должен принимать ввод, который является допустимым кодом C ++, и производить в качестве вывода более корректный код C ++. Плюс ко всем прочим ограничениям вашей системы сборки.
Входные данные должны быть, по крайней мере, очень близки к допустимому коду C ++, потому что, в конце концов, clang является интерфейсом компилятора, и мы просто ковыряемся и проявляем творческий подход с его API. Я не знаю, есть ли какое-либо положение, позволяющее определить новый синтаксис для использования, но ясно, что мы должны разработать способы его правильного синтаксического анализа и добавить его в проект clang, чтобы сделать это. Ожидать большего - значит иметь в проекте Clang что-то, что выходит за рамки.
Не проблема. Я полагаю, что некоторые неоперативные макро-функции могут справиться с этой задачей.
Другой способ взглянуть на то, что я описываю, - это реализовать конструкции метапрограммирования с использованием среды выполнения C ++, манипулируя AST нашего исходного кода (благодаря clang и его API) вместо того, чтобы реализовывать их с помощью более ограниченных инструментов, доступных в самом языке. Это также имеет явные преимущества в производительности компиляции (заголовки с большими шаблонами замедляют компиляцию пропорционально тому, как часто вы их используете. Множество скомпилированных материалов затем тщательно подбирается и отбрасывается компоновщиком).
Это, однако, происходит за счет введения дополнительного или двухэтапного процесса сборки, а также требования написания некоторого (по общему признанию) более многословного программного обеспечения (но, по крайней мере, это простая среда выполнения C ++) как части нашего инструмента. ,
Это не вся картина. Я совершенно уверен, что существует гораздо больший объем функциональности, который может быть получен при создании кода, что чрезвычайно сложно или невозможно с функциями основного языка. В C ++ вы можете написать шаблон или макрос или сумасшедшую комбинацию обоих, но в инструменте clang вы можете изменять классы и функции ЛЮБОМ способом, которого вы можете достичь с C ++, во время выполнения , имея полный доступ к семантическому контенту, кроме шаблонов и макросов и всего остального.
Итак, мне интересно, почему все еще не делают этого. Это то, что эта функциональность от Clang настолько новая, и никто не знаком с огромной иерархией классов AST Clang? Этого не может быть.
Возможно, я просто недооцениваю сложность этого, но «манипулирование строками во время компиляции» с помощью инструмента clang почти преступно просто. Это многословно, но безумно просто. Все, что нужно, - это набор неиспользуемых макрофункций, которые отображаются на реальные реальные std::string
операции. Плагин clang реализует это путем извлечения всех соответствующих макро-вызовов no-op и выполняет операции со строками. Этот инструмент затем вставляется как часть процесса сборки. Во время сборки эти вызовы макрокоманд без операции автоматически оцениваются в их результатах, а затем вставляются обратно в виде простых старых строк времени компиляции в программе. Затем программа может быть скомпилирована как обычно. Фактически, эта результирующая программа также намного более переносима, в результате не требуется новый модный компилятор, поддерживающий C ++ 11.