Каково происхождение препроцессора C?

30

Препроцессор C подключен к C, но его синтаксис совершенно отличается от основного языка:

  • синтаксически значимые пробелы (конец строки завершает оператор, пробел после макроса определяет начало списка замены)

  • блоки на основе ключевых слов вместо фигурных блоков elifвместоelse if

  • определения на основе ключевых слов вместо объявления-отражает-использование, нет =для определения значения

  • подсказки альтернативного строкового синтаксиса ( #include <>против #include "")

  • ленивая оценка (очевидно, C; но 6.10.3.1 может быть прочитан как подразумевающий определенный порядок макроразложения, а также в тех немногих местах, которые имеют значение)

Это действительно не похоже на C на всех! Технически это является его собственный язык, но он всегда был использован в качестве почти-неотъемлемая часть C , и кажется очень странным , что он не будет интегрироваться с ней синтаксически.

Википедия не говорит о своей истории; Портлендский репозиторий паттернов упоминает об этом мимолетно , но не вдавается в подробности, кроме того факта, что он был разработан другими людьми, чем остальная часть сайта С. Денниса Ричи с историей Си, вероятно, имел ответ, но, к сожалению, нет дольше доступны.

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

У нас есть какие-либо записи о том, почему он был разработан таким образом, или как повлияли создатели?

Leushenko
источник
5
archive.org/details/dmr-grab
Майк поддерживает Монику
@Mike, боже мой, спасибо, я действительно думал, что содержимое сайта потеряно навсегда, так как в нем нет просматриваемой записи в архиве
Леушенко
@MikeSupportsMonica Я собирался спросить, есть ли у кого-то ссылка. Спасибо.
klutt

Ответы:

17

С http://www.jslint.com/chistory.html («Развитие языка Си» Дениса М. Ричи):

Многие другие изменения произошли около 1972-3, но самым важным было введение препроцессора, частично по настоянию Алана Снайдера [Snyder 74], но также в знак признания полезности механизмов включения файлов, доступных в BCPL и PL / I. Его оригинальная версия была чрезвычайно простой и содержала только включенные файлы и простые замены строк: #include и #define макросов без параметров. Вскоре после этого он был расширен, главным образом Майком Леском, а затем Джоном Рейзером, для включения макросов с аргументами и условной компиляцией. Препроцессор изначально считался необязательным дополнением к самому языку. Действительно, в течение нескольких лет он даже не вызывался, если исходная программа не содержала специального сигнала в своем начале. Такое отношение сохранялось и объясняет как неполную интеграцию синтаксиса препроцессора с остальным языком, так и неточность его описания в ранних справочных руководствах.

Из описания в разделе 4 ссылки [Snyder 74], связанной в приведенной выше цитате, следует, что Алан Снайдер работал над переносным (сегодня можно сказать «ретаргетируемым») компилятором Си. Возможно, это и послужило мотивацией для запроса препроцессора.

Однако я не смог найти никаких дополнительных подробностей о дизайне самого препроцессора C как языка.

Джеймс Янгман
источник
1
Обратите внимание, что Снайдер пришел в Bell Labs из MIT, где ассемблер MIDAS имеет операторы DEFINE, IFDEF и IFNDEF. Совпадение?
Ларс Бринкгоф
0

Я мог бы просто добавить, что для ассемблеров было очень распространено иметь препроцессоры макроассемблера, которые очень похожи на CPP.

Tuntable
источник