Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 03:57
Оценка:
Кто хорошо знаком с историей C — подскажите, из каких соображений фаза препроцессирования была принципиально отделена от фаз компиляции, с постулированием, по сути, полного отсутствия связей между ними?

Соображениями простоты это объяснить не получается — препроцессор C крайне примитивен, ресурсов для реализации требует мизерных (в сравнении с ресурсами для последующей компиляции).

В то же время, будь там вместо препроцессора нормальный макрогенератор, частично связанный с собственно компилятором (например, по типам выражений/идентификаторов) — можно было бы еще в 70-е малой кровью делать ряд удобных вещей.

С ностальгией вспоминаю макрогенератор ассемблера System/360, воспроизведенный затем в трансляторе автокода БЕМШ для БЭСМ-6.
Re: Концепция препроцессора
От: Мёртвый Даун Россия  
Дата: 05.09.17 04:25
Оценка: +3 :))
Здравствуйте, Евгений Музыченко, Вы писали:

Вообще, не надо искать смысл там, где его нет. Я вот у нас в конторе частенько наблюдаю, как молодые сотрудники почему то свято уверены, что какие то решения в том числе и у нас в проектах, принимались чуть ли не консилиумом, сборищем супер инженеров в белых халатах... хыхы... Ан нет, просто в тот момент было быстрее костыль подставить покавырявшись в носу в течении 20 сек.

ЕМ>Кто хорошо знаком с историей C — подскажите


Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Отредактировано 05.09.2017 4:29 Мёртвый Даун . Предыдущая версия .
Re: Концепция препроцессора
От: Alexander G Украина  
Дата: 05.09.17 05:06
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>нормальный макрогенератор, частично связанный с собственно компилятором (например, по типам выражений/идентификаторов)


Лучше поздно, чем никогда _Generic in C11
Русский военный корабль идёт ко дну!
Re[2]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 05:55
Оценка:
Здравствуйте, Мёртвый Даун, Вы писали:

МД>Вообще, не надо искать смысл там, где его нет.


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

Мне бы такое даже в голову не пришло — гораздо логичнее встроить макрообработку в лексический анализатор, при этом вывод промежуточных результатов одинаково доступен и оттуда.
Re[2]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 06:03
Оценка: +1
Здравствуйте, Alexander G, Вы писали:

AG>Лучше поздно, чем никогда _Generic in C11


Такое — лучше никогда. Классическое решение для узкого класса частных случаев. Если уж расширять, то максимально абстрактно.
Re: Концепция препроцессора
От: alpha21264 СССР  
Дата: 05.09.17 10:44
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Кто хорошо знаком с историей C — подскажите, из каких соображений фаза препроцессирования была принципиально отделена от фаз компиляции, с постулированием, по сути, полного отсутствия связей между ними?


ЕМ>Соображениями простоты это объяснить не получается — препроцессор C крайне примитивен, ресурсов для реализации требует мизерных (в сравнении с ресурсами для последующей компиляции).


Первая реализация языка С делалась на машине PDP-11.
Собственно это объясняет всё.
Например, почему в С нет функции факториала.

ЕМ>В то же время, будь там вместо препроцессора нормальный макрогенератор, частично связанный с собственно компилятором (например, по типам выражений/идентификаторов) — можно было бы еще в 70-е малой кровью делать ряд удобных вещей.


Любой алгоритм можно описать всего тремя элементами — циклом, условием и вызовом подпрограммы.
Если тебе нужен PL/1 ты знаешь, где его взять (с).

Течёт вода Кубань-реки куда велят большевики.
Re[2]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 10:52
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Первая реализация языка С делалась на машине PDP-11.

A>Собственно это объясняет всё.

Что именно это объясняет, кроме наличия операций инкремента/декремента?

A>Например, почему в С нет функции факториала.


Чем объясняется отсутствие такой функции в большинстве остальных языков?

A>Любой алгоритм можно описать всего тремя элементами — циклом, условием и вызовом подпрограммы.


А это и вовсе не к месту и не в тему.
Re[2]: Концепция препроцессора
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.09.17 10:55
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Первая реализация языка С делалась на машине PDP-11.

A>Собственно это объясняет всё.
A>Например, почему в С нет функции факториала.

А как это объясняет отсутствие в stdlib функции факториала?

A>Любой алгоритм можно описать всего тремя элементами — циклом, условием и вызовом подпрограммы.

A>Если тебе нужен PL/1 ты знаешь, где его взять (с).

В языке Go, кстати, из 3-х видов сишных циклов остался только один
Re[3]: Концепция препроцессора
От: alpha21264 СССР  
Дата: 05.09.17 11:16
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, alpha21264, Вы писали:


A>>Первая реализация языка С делалась на машине PDP-11.

A>>Собственно это объясняет всё.

ЕМ>Что именно это объясняет, кроме наличия операций инкремента/декремента?


Ты наверное не знаешь, что такое PDP-11.
Это вычислительная машина с адресным пространством в 64 килобайта.
И с машинным словом длинной 16 бит.
И с системой команд, в которой строку удобно заканчивать нулём.

A>>Например, почему в С нет функции факториала.


ЕМ>Чем объясняется отсутствие такой функции в большинстве остальных языков?


А какие ты знаешь остальные языки?
Если они выросли из С как Java то объяснение очень простое.

A>>Любой алгоритм можно описать всего тремя элементами — циклом, условием и вызовом подпрограммы.


ЕМ>А это и вовсе не к месту и не в тему.


К месту и в тему.
Если бы ты писал программы а не языки (как Керниган и Ричи), то заковыристые возможности языка тебе были бы ни к чему.
Собственно и препроцессор ни к чему. Потому что смотря на программу ты видишь не то, что будет работать.

# define true false // приятной отладки, суки!

Течёт вода Кубань-реки куда велят большевики.
Re[3]: Концепция препроцессора
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.09.17 11:52
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

A>>Первая реализация языка С делалась на машине PDP-11.

A>>Собственно это объясняет всё.
ЕМ>Что именно это объясняет, кроме наличия операций инкремента/декремента?

Замечание по ходу — инкремент и декремент к PDP-11 ни при чём, сказал сам Dennis Ritchie.
Так что и их не объясняет
The God is real, unless declared integer.
Re[2]: Концепция препроцессора
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.09.17 11:56
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Первая реализация языка С делалась на машине PDP-11.

A>Собственно это объясняет всё.
A>Например, почему в С нет функции факториала.

Сюрприз — она есть в C. Хотя на PDP-11, да, её не было.

ЕМ>>В то же время, будь там вместо препроцессора нормальный макрогенератор, частично связанный с собственно компилятором (например, по типам выражений/идентификаторов) — можно было бы еще в 70-е малой кровью делать ряд удобных вещей.

A>Любой алгоритм можно описать всего тремя элементами — циклом, условием и вызовом подпрограммы.
A>Если тебе нужен PL/1 ты знаешь, где его взять (с).

При чём тут PL/1?
The God is real, unless declared integer.
Re[4]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 12:57
Оценка: 1 (1) +2
Здравствуйте, alpha21264, Вы писали:

A>Ты наверное не знаешь, что такое PDP-11.


Немножко знаю. Так, слегонца, на уровне начальных загрузчиков, драйверов ядра RSX-11M, и тому подобной мелочевки.

A>Это вычислительная машина с адресным пространством в 64 килобайта.

A>И с машинным словом длинной 16 бит.
A>И с системой команд, в которой строку удобно заканчивать нулём.

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

A>А какие ты знаешь остальные языки?


Если учитывать только ЯВУ, и на уровне "листал описание, написал несколько строк" — с десяткок. А сколько Вы знаете языков времен 60-70-х, где есть встроенный факториал?

A>Если они выросли из С как Java то объяснение очень простое.


И каково же Ваше простое объяснение отсутствия встроенного факториала в раннем C?

A>Собственно и препроцессор ни к чему. Потому что смотря на программу ты видишь не то, что будет работать.


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

A># define true false // приятной отладки, суки!


Такое можно учинить практически в любом из ЯВУ.
Re[4]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 13:08
Оценка:
Здравствуйте, netch80, Вы писали:

N>Замечание по ходу — инкремент и декремент к PDP-11 ни при чём


Конкретно PDP-11 ни при чем, а вообще DEC был одним из первых, кто реализовал аппаратный автоинкремент, так что сама идея где-то в тамошнем сообществе и родилась.
Re: Концепция препроцессора
От: Tilir Россия http://tilir.livejournal.com
Дата: 05.09.17 13:10
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Кто хорошо знаком с историей C — подскажите, из каких соображений фаза препроцессирования была принципиально отделена от фаз компиляции, с постулированием, по сути, полного отсутствия связей между ними?


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

Если сделать возможность встроиться в парсер, то получатся синтаксические макросы как в лиспе.

Почему именно в лексер? Потому что там больше возможностей. Рассмотрим простой пример: вам нужно манглировать имя функции в зависимости от дефайна времени компиляции. То есть чтобы функция называлась по умолчанию foo0, но, если определена DFOONAME=1 то foo1 и так далее. На этапе когда все лексемы уже сформированы, вы этого сделать просто не сможете. Аналогично вы не смоете стрингифицировать и конкатенрировать (## и #). Так что именно сишный препроцессор рулит.
Re[2]: Концепция препроцессора
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.09.17 13:31
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>Почему именно в лексер? Потому что там больше возможностей. Рассмотрим простой пример: вам нужно манглировать имя функции в зависимости от дефайна времени компиляции. То есть чтобы функция называлась по умолчанию foo0, но, если определена DFOONAME=1 то foo1 и так далее. На этапе когда все лексемы уже сформированы, вы этого сделать просто не сможете.


Вот именно поэтому он и _не_ рулит, и возможностей меньше.
Ты меняешь foo на foo1, но в результате у тебя заменились все foo: и функции, и локальные переменные, и функция в другом пространстве имён (а без пространств рано или поздно язык превращается в аццкий хламовник — именно это случилось с C).
Замена на уровне синтаксиса позволит заменить именно нужный foo, а не все подряд.

T> Аналогично вы не смоете стрингифицировать и конкатенрировать (## и #). Так что именно сишный препроцессор рулит.


Это тоже делается на уровне уже синтаксиса, хоть и сложнее, но возможностей там больше (например, для Java стиля при конкатенации полезно менять регистр по типу zuka -> getZuka — сишное # такого не сумеет).
The God is real, unless declared integer.
Re[2]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 14:10
Оценка:
Здравствуйте, Tilir, Вы писали:

T>На этапе когда все лексемы уже сформированы, вы этого сделать просто не сможете.


Я в первую очередь имел в виду не сами фазы трансляции, а объем информации, которой владеет компилятор. Например, классический #ifdef работает только со списком макроопределений, подразумевая, что препроцессор может быть реализован независимой утилитой, как это сделано в *nix. Но я не вижу ровным счетом никакого смысла в таком искусственном разделении. А при реализации макрообработки в составе компилятора параметр #ifdef мог бы проверяться заодно и по спискам объявленных типов, переменных, функций. А в #if можно было бы реализовать операции вроде typeof (а sizeof таки реализовали в Turbo C).

Потом, даже простейшая доработка в виде многострочных макросов, в составе которых допустимы #if, резко расширяет возможности макрогенерации. Это есть в любом неигрушечном макроассемблере, и реализуется достаточно просто.

Ну и потом, кто заставляет выполнять этапы строго последовательно, по канонам и заветам? Даже на этапе синтаксического анализа можно в любой момент вызвать лексер, а затем запустить анализ конструкции заново.
Re[3]: Концепция препроцессора
От: alpha21264 СССР  
Дата: 05.09.17 14:21
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, alpha21264, Вы писали:


ЕМ>>>В то же время, будь там вместо препроцессора нормальный макрогенератор, частично связанный с собственно компилятором (например, по типам выражений/идентификаторов) — можно было бы еще в 70-е малой кровью делать ряд удобных вещей.

A>>Любой алгоритм можно описать всего тремя элементами — циклом, условием и вызовом подпрограммы.
A>>Если тебе нужен PL/1 ты знаешь, где его взять (с).

N>При чём тут PL/1?


Ну вот Керниган считал, что причём. Это его слова.
Хрестоматийный пример того, что не надо тянуть в язык всё, что напридумала фантазия.
К С/С++ тоже относится.

Течёт вода Кубань-реки куда велят большевики.
Re[3]: Концепция препроцессора
От: Tilir Россия http://tilir.livejournal.com
Дата: 05.09.17 16:36
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ну и потом, кто заставляет выполнять этапы строго последовательно, по канонам и заветам?


Стандарт языка. Почитайте C11 (у меня n1570) 5.1.1.2 например. Фазы трансляции прописаны очень жёстко.
Re[4]: Концепция препроцессора
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.09.17 19:15
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Стандарт языка.


Какой еще "стандарт языка" в начале 70-х?
Re[5]: Концепция препроцессора
От: Tilir Россия http://tilir.livejournal.com
Дата: 05.09.17 19:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Какой еще "стандарт языка" в начале 70-х?


А вы про этап разработки. Я думал вы уже высказываете идеи как доработать существующий. Ну тогда просто не знали как правильно делать. Когда на всё наступили, сделали правильный и мощный m4.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.