2013-05-08 2 views
2

Я рассматриваю возможность реализации языка высокого уровня (Lisp-like) путем компиляции через C (или, возможно, C++, если исключения оказываются достаточно полезными); это стратегия, которую ранее использовал ряд проектов. Конечно, это создало бы код С в отличие от, и, возможно, в некоторых измерениях, превышающих сложность, все, что вы могли бы написать вручную.Компиляция через C/C++ и ошибки/пределы компилятора

Современные компиляторы C очень надежны при нормальном использовании, но трудно понять, какие ошибки могут скрываться в кросс-футлярах при необычных нагрузках, особенно если вы переходите на некоторые «ну, ни один программист никогда не напишет X больше, чем Y» скрытый предел.

Мне кажется, что совпадение этих фактов может привести к несчастью.

Есть ли какие-либо известные случаи, или есть хороший способ найти случаи, сгенерированный код с ошибками/ограничениями в случае ошибок в предельно поздних версиях основных компиляторов (например, GCC, Microsoft C++, Clang)?

+0

Или просто использовать LLVM. Или, если вы мазохист (как я), напишите простой парсер, который генерирует C, когда он ходит по (возможно, неявному) дереву разбора. – 2013-05-08 19:05:17

+0

Не знаете, что вы намерены использовать с «краевыми случаями», но списки известных ошибок обычно легко доступны, если вы их ищете (например, http://gcc.gnu.org/bugzilla/query.cgi) – Svalorzen

+0

LLVM - это возможность. Он теряет некоторые из больших преимуществ C (например, легкость отладки вывода глазным яблоком), сохраняя при этом других (например, существующий репертуар низкоуровневых оптимизаций). В любом случае возникает один и тот же вопрос: есть ли способ заранее узнать, какие ошибки вы могли бы отключить с кодом LLVM, в отличие от всего, что было бы от рукописного C? – rwallace

ответ

1

Возможно, это не совсем тот ответ, который вы искали, но довольно много лет назад я работал над проектом, где части системы были написаны на более высоком уровне языка, где было легко создавать государственные машины в процессах. Этот язык создал C-код, который затем был скомпилирован. Компилятор, который мы использовали для этого проекта, был gcc (версия около 2.95 - не цитируйте меня на этом, но до версии 3.0 наверняка). Мы столкнулись с несколькими ошибками генерации кода, но это из-за моей памяти больше связано с использованием не очень популярного процессора [выявление того, какой процессор может выявить что-то, что я не должен был делать с проектом, поэтому я предпочел бы не сказать, что это было, даже если это было очень давно].

Коллега, близкая мне, изучала одну из таких ошибок генерации кода, которая находилась в функции около 200 тыс. Строк, причем вся функция представляет собой большой оператор switch-statement, причем каждый случай в заявлении коммутатора составляет около 50-1000 каждый из них (с несколькими слоями подзаголовков в нем).

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

Мое замечание состоит в том, что современные компиляторы допускают много большого кода. Существуют также минимальные ограничения, которые «совместимый компилятор должен поддерживать как минимум». Например, я верю (из памяти еще раз), что компилятор должен поддерживать 127 уровней вложенных операторов (т. Е. Комбинацию из 127, если, переключатель, while и do-while) внутри функции. И из обсуждения где-то (откуда и происходит «компилятор должен поддерживать 127 уровней вложенных операторов»), мы обнаружили, что MSVC и GCC поддерживают намного больше (достаточно, чтобы мы отказались от поиска ...)

0

Это может показаться очевидным, но единственный способ узнать это - тестирование. Если вы не можете приложить все усилия самостоятельно, по крайней мере, сделайте свой продукт кросс-платформенным, чтобы люди могли легко протестировать вас! Если людям нравится ваш проект, они, как правило, готовы представить отчеты об ошибках или даже патчи бесплатно :)

+0

Да, кросс-платформенная определенно находится в списке приоритетов. Личный опыт, безусловно, самый эффективный способ узнать, если мы игнорируем стоимость, но это также может быть очень дорого. Если бы я мог потратить несколько часов на чтение отчетов о чужих переживаниях и принять лучшее решение, а не недели или месяцы, сначала изучая трудный путь, это будет большой победой. – rwallace

+1

Один практический совет - когда вы сами тестируете свои результаты, запустите свой компилятор C с очень агрессивными настройками (например, gcc -pedantic), чтобы убедиться, что ваш выход очень портативен. Также имеет смысл использовать C вместо C++ - C (версия 1989 года) по-прежнему остается самым переносимым языком в мире.Кроме того, у C++ гораздо больше шансов получить ошибку нечетного компилятора из-за того, что C++ намного больше и сложнее. Это происходит из личного опыта с трудом ... –

1

Короткий ответ:

У вас нет выбора, если вам нужна производительность компилятора, а не легкость жизни переводчика (или прекомпилятора + переводчика). Вы будете компилировать на какой-то язык более низкого уровня, а C - язык ассемблера сегодня, причем C++ доступен как доступный и как подходящий для задачи как C. Нет причин, по которым вы должны бояться этого маршрута. Это, в некотором смысле, очень общий маршрут.

Длинный ответ:

Сгенерированный код ни в коей мере необычным. Даже относительно скромное использование сгенерированного кода приводит к источнику C, который «в отличие от того, что когда-либо писал любой программист», с точки зрения количества (тривиальные шаблоны кода, повторяющиеся с небольшими изменениями в миллионы раз), или качества (комбинации языковых функций, которые человек никогда не будет использовать, но это все еще, скажем, юридический C++). Существует также немало компиляторов, которые компилируются на C или C++, some famous и хорошо известны людям, которые написали стандарты языка C и C++.

Наиболее распространенные компиляторы C и C++ хорошо справляются с сгенерированным кодом. Да, они никогда не совершенны.

  • Компиляторы могут иметь различные простые ограничения, такие как максимальная длина кода длина; они, как правило, документируются и легко соблюдаются в вашем генераторе, когда вы сталкиваетесь с ними.
  • У компиляторов могут быть дефекты.
    • Некоторые виды дефектов на самом деле нет озабоченности по сгенерированному коду, чем для рукописного кода. Ваш генератор кода на самом деле дает вам определенную свободу во многих ситуациях систематически, как только вы начинаете понимать шаблон и заботиться о проблеме.
    • Дефекты, которые фактически приводят к тому, что компилятор не компилирует правильный код правильно, быстро обнаруживаются, учитывая достаточное количество пользователей компилятора. Они обрабатываются поставщиками компиляторов как особенно высокоприоритетные дефекты.Даже если компилятор по существу мертв или работает на нишевом рынке, так что никакое исправление не доступно, в Интернете доступно множество информации, в том числе опыт работы с дефектом людей (разные компиляторы, другая конструкция кода, другой компилятор переключатели ... решение сильно варьируется и может показаться неудобным, но никто не отказывается от своей работы только потому, что какое-то программное обеспечение ошибочно, правильно)? Таким образом, обычно есть выбор доступных для поиска решений.

Это часто хорошо стремление к мобильности через составителей, но и знать и отслеживать пределы переносимости. Если вы не очень хорошо тестировали компилятор C или C++, не утверждайте, что он будет работать как часть вашего набора инструментов.

Вы задаете подразумеваемый вопрос между C и C++. Ну, здесь больше оттенков серого. C++ - очень богатый язык. Вы можете использовать почти все возможности C++ для хороших целей в вашем генераторе, но в некоторых случаях вы должны спросить себя, может ли какая-то важная функция стать ответственностью, которая стоит вам больше, чем она приносит вам. Например, разные компиляторы используют разные стратегии для создания экземпляра шаблона. Неявное создание экземпляров может привести к непредвиденной сложности с переносимым сгенерированным кодом. Если шаблоны действительно помогают вам создавать генератор чрезвычайно, не стесняйтесь использовать их; но если у вас есть только крайний прецедент для них, помните, что у вас есть лучшая причина, чем большинство людей, чтобы ограничить язык, в котором вы создаете.

1

Существуют все виды реализации определенных пределов в C. Некоторые четко определенные и видимые для программиста (считайте числовые ограничения), другие - нет. В моей копии проекта стандарта, раздел 5.2.4.1 Детальнее нижние границы этих пределов:

5.2.4 Экологические ограничения

Оба перевода и исполнения среды ограничивают реализацию языка переводчиков и библиотек. Нижеследующее обобщает связанные с языком экологические ограничения на соответствующую реализацию; пределы библиотеки, связанные которые обсуждаются в разделе 7.

5.2.4.1 пределы Translation

Реализация должна быть в состоянии перевести и выполнить хотя бы одну программу, которая содержит, по меньшей мере, один экземпляр каждого из следующих пределы: 18)
- 127 уровней вложенности блоков
- 63 уровней вложенности условного включения
- 12 указатель, массив, и функция declarators (в любых комбинациях), модифицирующие арифметической, структуры, объединения или пустот типа в декларации
[...]


18) Реализации должны избегать введения фиксированных ограничений на перевод, когда это возможно.

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

Что касается ошибок:

Clang - http://llvm.org/bugs/buglist.cgi?bug_status=all&product=clang
GCC - http://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=all&product=gcc
Visual Studio - https://connect.microsoft.com/VisualStudio/feedback

Смежные вопросы