LINUX.ORG.RU

О божественном C и введение в него через ed

 , ,


4

2

Бытие (частично) определяет.

*Какая регулярка преобразует for с телом в while с телом ?

*Какой #define макрит for в while?

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

Ответ на: комментарий от qulinxao3

в первой половине 80ых системный софт писался больше на Паскаль-языках ( Ада +- в этом поддереве) как ни очевидно

Да, на паскале писалось много системщины. Про «больше» - это еще вопрос. Тот же AT&T писал свой софт на Си, а это был крупнейший потребитель софта на земном шарике того времени. CP/M, предок MS DOS, вообще на PL/M был написан (не путать с сильно отличающимся PL/I). PL/M появился в 1973, если что, то есть, позже Си.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

источники открыты - на битсэйвере например

на tuhs например

даже упоминание в предисловии K&R о наличии 10 машин на которых есть Сишка приобритает оттенки при натыкании в мема(рандумах) о Паскале/любой_другой_язык в рассылках тех лет заявлениях что том что язык притащан на такую то платформу.

..

дело не в альтернативах которых было полно и о которых и тогда мало кто знал.

дело о восприятии прошедшего(а скорее того что известно о ) как единственно возможного.

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

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от qulinxao3

AST по факту графы.

Да. Но графы - не AST. Очевидно, если мы отказываемся от синтаксического дерева, то у нас должны быть недревовидные графы. Теоретически программу можно представить в виде недревовидного графа, но практически смысла в этом нету.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

для закругления - строгий хронологический порядок важная улика но не основная

т.е. подобно топологической сортировке в которой не на всех парах задан порядок следования.

в своё время теория акторов ( взаимодействующих процессов - в предисловии к которой было упомянуто о том что сия теория акторов создана на основе той теории в которой конечно распространения взаимодействия (какая то из относительностей)) - помогла понять как саму теорию акторов так и лучше понят что же такого реально в объектах и их взаимодействии (где не ОДИН всеведующий вычислитель обсчитывает последовательно все места мира) так и саму теорию относительности с конечной скоростью максимального взаимодействи.

sic!

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от byko3y

AST как минимум DAG - ибо не свободны от контекста

будь свободность от контекста было бы достаточно однопроходных нисходящих парсеров.

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от qulinxao3

даже упоминание в предисловии K&R о наличии 10 машин на которых есть Сишка

Оригинал звучит как «The number of UNIX installations has grown to 10, with more expected», что не согласовывается с недопустимо вольным пересказом.

дело не в альтернативах которых было полно и о которых и тогда мало кто знал

Каких? Имя, сестра, имя.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

архивы открыты

проблема моего указание имени твоих сестер приведён к спору о валидности.

если реально есть интерес то можно по первоисточникам увидеть более детальную картину чем шаржи масмедиа

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от qulinxao3

AST как минимум DAG - ибо не свободны от контекста

AST/DAG не являются языками, потому бессмысленно говорить об их контексто-зависимости/независимости.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

ригоризм отличительная черта специфических экзаменаторов.

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от byko3y
Ответ на: комментарий от qulinxao3

я тут паскалей принёс, очередной линкдамп

как килерапликуха VisiCalc для ваще рынка перс.компов в офисах.

SuperCalc под ДОС рулил, да. он ещё и под CP/M был, оказывается.

ща плотнее ознакамливаюсь с историей Pascal -0 -4 -P0 -P4 и как оно плесенораспространялось и есть некоторое зерно в утверждение Вирта что килерапликуха Unix для языка Си

это не Тимохин, это ЕМНИП, Терешков: XD Pascal под выньдовз xdp под MSDOS хабраблог

и очередной линкдамп: pascal p5 wiki pascal p5c:

p5c is a fast portable iso standard pascal compiler.

It is derived from the pascal p5 compiler and creates gnu c code instead of p-code.

подборка паскалей: p4, p5, web, super, xdp у него же: pl0rx на implish (старый implish = imp-pas) => PL0-LanguageTools standard pascal

и старое под CP/M (CP/M 86, лол, C64 ): Pascals CP/M UCSD также там про модулу и про Аду – DOS Ada Compiler, SmallADA

p5 compiler Pascal Implementation: A Book and Sources книжечка собственно, pcode

вышел на них через bootstrappable.org и wiki. дальше не помню. может ещё какие ссылки вспомню, но не так сразу.
доктор оллком спайдер и джонни мнемоник, фальшивая память и Nerve Attenuation Syndrome, чума нашего времени. и все дела.

есть любопытные реализации паскаля. раскрученные «сами на себе».

anonymous
()
Ответ на: я тут паскалей принёс, очередной линкдамп от anonymous

«тут» речь не о Пацсаль asis и прочие Блезы - а достаточный для самораскрутки рекурсивный нисходящий парсер с скажем следом в 4K 64бит слов x64

Обероны и прочие короли Эльфов дозволяются

целевая функция обозримый рекурсивный нисходящий парсер с соответсвенно упрощённой грамматикой с достаточной [s]ортагональностью[/s] ни_избыточностью

т.е эдакий B для x64 c расширяемыми структурами

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от byko3y

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

это как «внутри С++ есть какой-то простой язык, который пытается выбраться наружу». только он почти как метапрог – никто не понимает, что это такое. потому что у каждого свой метаязык, своё подмножество этого «простого» языка.

фактический стандарт. ну давай. это – ad hoc бюрократизация, кодификация сложившейся глупости и предубеждений или всё-таки нечто продуманное, на основании принципов?

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

а не ad hoc «фактического стандарта».

и какая разница, сколько лет разрабатывали этот язык? сколько лет его стандартизировали? сейчас, по прошествии лет 50-60 это уже всё равно. главное, что получилось в итоге.

Продвинутые возможности препроцессора в PL/I используются в 0.1% случаев,

потому что эта фича не влезла в первую итерацию стандарта. и нормально была реализована только в компиляторах от ибм. ну да, как бы пл1 это язык ибм. но альтернативные реализации ниасилили – в первую очередь, отладку с интроспекцией и препроцессор. поэтому развились упрощённые PL/M, PL/S и прочие subset G. из которых и получилось в итоге нечто годное, как тот же PL/I-KT реализация.

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

и в чём проблемы? проблемы уровня embedded C++: ограничьте RTTI, шаблоны, исключения, поскольку в некоторых реализациях компиляторов их могут ниасилить. тут шерифа не волнуют – если есть правильная реализация, которая препроцессор и макросы поддерживает.

не знаю, насколько оно повсеместно применялось из-за этого. что конкретный компилятор может ниасилить.

но по-моему, эта фича – макросы – полезна, и ей есть место в toolchest программиста. если пользоваться ей грамотно, по уму. а не «ниасиливать макросы».

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

проблема не в том, что макросы это плохо. а в том, что в половине языков макросы это тупая подстановка строк – а не структурных выражений, позволяющий сконструировать свой язык. сначала тупое питушение строчек, пытаясь собрать строчку для компилятора. где-то совсем убогое, как в С, где-то чуть помощнее – как в PL/I где можно конструировать строки, но тоже строчно-ориентированное, что убого. потому что конструкция твоего метаязыка может в одну строчку и не поместиться. и эта конкатенация по сути монада моноид в категории эндофункторов, монада строк, списков, структурных выражений. так что нужно не «тупое питушение строк» и не менее «тупое питушение списков» с кодеволкером вручную, сколько сразу, конструирование структурных выражений. по возможности, с типизацией. которую обеспечивает компилятор.

Безконтрольное, неограниченное метапрограммирование создает большие проблемы в поддержке проекта, в совместимости на разных платформах.

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

anonymous
()
Ответ на: комментарий от byko3y

Почему ты не хочешь сравнить PL/I с паскалем?

а я и хочу – просто до этого ещё не добрался. и с паскалем, и с адой как продвинутым паскалем. и с алголом, их предком. проблема пл1 в том, что он появился как гибрид ужа с ежом – то есть, фортрана с коболом. в итоге пытаясь скрестить из двух полезных DSL для инженеров и BCD для рублей копеек с одинэсом шестидесятых годов родили нечто громоздкое ибо универсальное, чересчур универсальное.

потому что опять же, язык должен быть полностью специфицирован, не должно быть никаких UB на уровне стандарта, язык-машины – и затем, реализации тоже.

Это я уже не говорю, что автор статьи - мудак, и делает очень поверхностное сравнение

а по-моему, достаточно глубокое. есть язык, спроектированный чтобы не было никаких UB, и с этой точки зрения проектные решения в его основе вполне разумны. и есть ad hoc кодификация глупости фактического стандарта (ибо реальные компиляторы формальный ниасиливают, и/или он избыточно сложен. так и появляется ещё один стандарт реализации языка – уже де факто).

anonymous
()
Ответ на: комментарий от byko3y

Parser Tree - это Concrete Syntax Tree, потому очень близко к AST.

это не обязательно, и так у не только лишь всех. например, Евгений Зуев, в Interstone и их реализации компилятора С++ сделал семантическое дерево, а не синтаксическое – чуешь разницу? а она есть.

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

просто где-то эта семантика выражена явно (например, в каком-то nanopass compiler framework это может быть просто отдельный проход компилятора), где-то неявно в ad hoc реализации компилятора.

опять же, чем яснее стандарт и спецификация – тем чётче можно выделить такие проходы и их цели. например, если сравнивать стандарт ANSI Common Lisp (который слепили из того что было: MacLisp, InterLisp, ZetaLisp и прочие лиспы начала 80х) и более продуманный ISO ISLISP где пытались выделить процессор, модульность, все типы – объекты, и т.п.

то даже визуально видно: один стандарт на тыщу страниц, другой на сто. третий, например kernel scheme с vau expressions и fexprs – ещё короче (но у него более сложная математика).

или вообще оберон с описанием грамматики, типов и объектов. на 15-30 страниц.

а значит, и реализовать его корректно – проще.

Смотря какие интерфейсы имеются в виду

Любые интерактивные интерфейсы.

рекомендую ознакомиться с работами проекта FONC/STEP и парсера OMeta в духе META II только объектно-ориентированного, ибо первоначальная реализация была на смоллтоке. и например, статьи про «Parsers running backwards».

когда именно богатость внутреннего представления IR (есть ссылка на родителей, на предыдущую стадию) позволяла прокрутить задом наперёд. например, автоматически реализовать pretty printing. или закачать AST в виде CST первого исходного языка, а выдать-транспилировать через pretty printing на другом, таким образом выполнив перевод на другой язык программировния автомагически

anonymous
()
Ответ на: комментарий от byko3y

а Plankalkul был высокоуровневым.

anonymous
()
Ответ на: комментарий от byko3y

Ты так и не ответил, что будет вместо дерева.

гиперграф из OpenCyc, например. только упрощённый, урезанный. или дерево конфигураций при суперкомпиляции Турчина (а не той, что в хаскелле) – где граф свёрнут ибо похожие конфигурации в дереве свёрнуты, мемоизированы при прогонке.

или вот то самое из parsers running backwards, которое довольно примитивно, но уже может

anonymous
()
Ответ на: комментарий от qulinxao3

факт в том что Сишка(для ригористов доРитчи сишка) - автором re-механизма. синтез идей всё такое.

только re Томпсона (который может быть быстрым и простым, а у всех неправильные и медленные, см. статью Russ Cox) и структуральные регэкспы Пайка – уже немного другие регекспы. которые уже могут.

anonymous
()
Ответ на: комментарий от byko3y

Также существовали совсем уже абстрактные астронавты с лиспом, где метаметапрограммы создавали метапрограммы, создающие программы.

(1)

Хочешь заниматься системщиной? Даже просто написать свой компилятор - добро пожаловать в мир ассемблера.

(2)

из (1) не следует (2), а даже наоброт. (1) совершенно ортогонально (2).

компилятор можно написать на любом языке, который умеет читать и писать файлы. да хоть на том же postscript.

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

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

не важно, изначально он на лиспе был разработан или где.

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

абстрактные астронавты с лиспом, где метаметапрограммы создавали метапрограммы, создающие программы.

в лиспе деревья бинарные, вот это car cdr регистры той машины.

ещё можно сделать SECD машину, специально под лисп.

ещё можно сделать как Ian Piumatra на схеме, объектной модели COLA и каком-то недосмолтоке.

ещё можно сделать как в рефале – где в рефал машине деревья произвольные, а не только лишь бинарные. или сшивки между деревьями, гипердеревья, гиперграфы.

абстрактные астронавты с абстрактным лиспом, где абстрактные метаметапрограммы абстрактно создавали абстрактные метапрограммы, абстрактно фабрично создающие абстрактные программы.

которые потом всё-таки могли быть специализированы в конкретный объектный язык из этой башни метаязыков. например, тот же ассемблер. только уже любой, любой машины – или виртуальный ассемблер с бесконечным количеством регистров типа LLVM SSA представление.

anonymous
()
Ответ на: комментарий от byko3y

«Мы выше грязной системщины» - говорят те же люди, которые в 2020 году создают вот такой мусор: From CIL to Java bytecode: Semantics-based translation for static analysis leveraging

да, статический анализ и байткод недостаточно системен. только bootstrapping compiler from nothing – только хексы, только хардкор.

всё остальное мусор же.

anonymous
()
Ответ на: комментарий от byko3y

Они на скорую руку клепают что-то, отдаленно напоминающее язык программирования. Потом приходят другие люди, смотрят на эту картину, и удивляются «ух ты, а так можно было?».

а потом все эти люди мучаются, ибо руки скорые, а головы пустые, недостаточно продуманные. и зачем так делать если всё равно придётся переделывать? может лучше придумывать тщательнее, дабы перепридумывать не пришлось?

anonymous
()
Ответ на: комментарий от byko3y

где-то до 2000 года борьба продолжалась. Borland признало поражение в 2003,

даже раньше, в 80х-90х когда JPI Modula/Pascal/C++ и этот Jen ушёл из Borland (или его ушли) – потому что не разивали модулу, это было началом конца. в 2000х с .NET и Хейлсбергом сбежавшим в микрософт, уже добили агонизирующее.

однако, курилка жив и как-то и до сих пор трепыхается.

anonymous
()
Ответ на: комментарий от byko3y

Паскалю понадобилось еще лет 5-10, чтобы выйти по системщине на тот же уровень, поскольку паскаль тогда больше напоминал жаву, нежели Си, то есть, язык для виртуальной машины, абстрагированной от платформы — время было потеряно, Си уже окопался, и выбить его из ниши было сложнее.

я вот примерно в то время, в 1985 прочёл K&R по языку Си, Кернигана и Пайка, довольно практичную, с примерами и упражнениями – после которой руки зачесались чего-нибудь запрограммировать, и книжку по паскалю какую-то довольно абстрактную. потому что диалект паскаля был описан ХЗ какой, и реализация комплиятора ХЗ какая. где не было модулей, unit, стандартной библиотеки, вообще ничего кроме readln/writeln. которые почему-то тоже предопределённые операторы, а не функции из стандартной библиотеки.

угадай, что показалось более практичным и на чём захотелось программировать в первую очередь.

а потом увидел жёлтую книжку по паскалю (лет через 8) со структурами данных со стрелочками. и паскаль оказался не так уж и плох.

а если бы попалась вот эта книжка или про P4/P5/PL0 реализации паскаля, да хоть того же Вирта – наверное, я бы по другому его воспринимал?

мне правда, ещё тогда попалась распечатка Креншоу «Let’s make a compiler» с реализацией на ассемблере. он ещё потом её на форт переписал, стало компактнее, и что удивительно, даже понятнее.

и я начал чего-то подозревать. потом когда столкнулся с турбо паскалём и очень быстрой, конкретной отдачей edit-compile-run а не «подожди, пока инклуды с темплейтами скомпелируются». то тоже получилось очень практично. вопреки первоначальному ощущению по той сине-серой книжке с абстрактной реализацией абстрактного недопаскаля. а не конкретно мощного турбо. или вышескоростного TopSpeed Modula/Pascal/C++.

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

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

иначе получается сравнение конкретного ежа из своей практики или воспоминании о нём с абстрактным скользким ужом, к которому непонятно как подступиться. и куда там «кобылу впрягать».

anonymous
()
Ответ на: комментарий от byko3y

Юникс родилась из чего-то, похожего на зародыш MS DOS - там очень уж примитивные фичи были у их однозадачной системы.

Multics? да, очень простая система. LOL, kek.

anonymous
()
Ответ на: комментарий от byko3y

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

literate programming и eludicateve lucid learning, например. или рефал с суперкомпиляцией и проекциями Футамуры-Турчина. конкретный практический смысл.

anonymous
()
Ответ на: комментарий от qulinxao3

т.е. подобно топологической сортировке в которой не на всех парах задан порядок следования.

частично упорядоченная решётка, и гомеоморфное вложение из рефала, Турчина. о, на эту тему следует meditate. и помедитировать тоже.

anonymous
()
Ответ на: комментарий от qulinxao3

достаточный для самораскрутки рекурсивный нисходящий парсер с скажем следом в 4K 64бит слов x64

целевая функция обозримый рекурсивный нисходящий парсер с соответсвенно упрощённой грамматикой с достаточной ~~ортагональностью~ не_избыточностью

да тот же Креншоу с «Let’s build a compiler»

в форт реализации ещё компактнее и понятнее (исходная была на ассемблере).

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

алсо, в плане метаязыков. можно взять HLA сайт вики

как более функциональный паскалесинтаксис, цепепе семантика (даже STL вкорячили) плюс объекты плюс функции без фрейма типа naked на сишечке со своим calling convention возможным, плюс это всё-таки ассемблер, хоть и синтаксис у него странный, типа функции-выражения.

в качестве анекдота.

anonymous
()
Ответ на: комментарий от anonymous

общество в котором ….

Бог-Император

логика юристов очень ориентированна на способность людей лести

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от anonymous

это как «внутри С++ есть какой-то простой язык, который пытается выбраться наружу». только он почти как метапрог – никто не понимает, что это такое. потому что у каждого свой метаязык, своё подмножество этого «простого» языка.
фактический стандарт. ну давай. это – ad hoc бюрократизация, кодификация сложившейся глупости и предубеждений или всё-таки нечто продуманное, на основании принципов?

Объясняю конкретно. C89 в основном ввел понятия прототипов функции и ключевых слов «volatile» и «const». По сути, прототипы функций - единственная полезная фича, несмотря на минимальные подводные камни:
https://gcc.gnu.org/onlinedocs/gcc/Function-Prototypes.html#Function-Prototypes
Тут скорее вопрос к K&R - почему язык столько лет просуществовал без типов формальных аргументов функции?

Далее, const - совершенно бесполезный модификатор, если учесть, что касты указателей неограничены, а преимуществ для оптимизиторов он не дает:
https://theartofmachinery.com/2019/08/12/c_const_isnt_for_performance.html

А теперь объясняю про проблемы volatile. В x86 по канону применяется барьер release для абсолютно всех операций, но другие архитектуры процессоров (SPARC, POWER, PowerPC, MIPS) таких гарантий не дают. Однако, даже в x86 порядок чтений по умолчанию не гарантируется. Внеочередное выполнение было известно уже в 1964 году, так что отмаза плана «ну мы не знали ничего про внеочередное исполнение» не прокатывает:
https://en.wikipedia.org/wiki/IBM_System/360_Model_91
https://en.wikipedia.org/wiki/POWER1 - 1990
Особенно эта отмаза не прокатывает в C99.

И что же мы теперь получили с volatile: программа будет читать значение из ячейки в памяти, но операции чтения могут быть переставлены местами, и программа прочитает «тухляк», увидит новое значение в первой строчке своего выполнения, но старое значение во второй строчке, что может адово поджигать пуканы, например, любителям писать синглетоны.
На этот случай в комитетах действует правило: комитет не может обосраться дважды. Потому «исправления» предыдущих комитетов никогда не исправляются во второй раз. В итоге только в C11 добавили атомики:
https://en.cppreference.com/w/c/atomic/atomic_init
https://en.cppreference.com/w/c/atomic/atomic_load
Здесь я просто хочу, чтобы вы запомнили аргумент: volatile не подходит для многопоточных приложений. А значит зачем он вообще нужен? Правильно, для оптимизации кода, чтобы глобальные переменные стали как бы не глобальными, а глобально-кэшированными.

Теперь перейдем к вопросу о том, что же должен был сделать комитет вместо volatile. Для этого зададимся вопросом «почему в паскале нет проблемы volatile, а в Си, Фортране, и Коболе - есть?». А потому что Си сам толкает программиста на использование глобальных переменных, в том числе в виде локальных переменных с модификатором «static». Естественно, когда создатели компиляторов видят это дело, то они хватаются за голову «у вас все переменные глобальные, но используете вы их локально. Как нам это говно оптимизировать?». И вместо того, чтобы послать лесом весь устаревший софт (который и дальше будет читать/писать глобальную память) и сделать новые конструкции для описания локальных переменных локальными и потому оптимизируемыми - бездарные дауны из комитета добавили volatile, действуя по методу наименьшего сопротивления в комитетном бурлении говен.

На этом фоне, к слову, выскочил C++, который имел фичу локального контекста, и это взлетело, да еще и как взлетело.

Давайте рассмотрим типичную такую задачу: взять контейнер, содержащий какие-то вещи, пройтись по каждому его элементу и применить к нему операцию. Если у вас задача простая, вроде «увеличить каждое значение на один», то можно обойтись простым указателем на функцию. С более сложными случаями такое не прокатит, например: взять элементы, у которых со значение ключа содержится в некоем массиве-аргументе, и применить к этим элементам замену слов по другому аргументу-словарю. K&R грят, что делать нужно вот так:

typedef struct {
  char *original;
  char *new;
} dict_element;

static int funcname_dict_count;
static dict_element *funcname_dict;
static int funcname_key_count;
static int *funcname_keys;

void funcname(container_element *element) {
  if (key_in_array(element->key, funcname_keys, funcname_key_count))
  ...
}

int main() {
  ...
  fill_keys(&funcname_keys, &funcname_key_count);
  fill_dict(&funcname_dict, &funcname_dict_count);
  container_for_each(container, &funcname);
  ...
}

В современном коде, вроде ядра линукса или Win API, это бы сделали как-то так:

typedef struct {
  char *original;
  char *new;
} dict_element;

typedef struct {
  int key_count;
  int *keys;
  int dict_count;
  dict_element *dict;
} funcname_args;

void funcname(container_element *element, funcname_args *args) {
  if (key_in_array(element->key, args->keys, args->key_count))
  ...
}

int main() {
  ...
  funcname_args args;
  fill_keys(&args->keys, &args->key_count);
  fill_dict(&args->dict, &args->dict_count);
  container_for_each(container, (container_for_each_function)&funcname, args);
  ...
}

Для таких задач в C++11 наконец придумали замыкания:

typedef struct {
  char *original;
  char *new;
} dict_element;

int main() {
  ...
  static int dict_count;
  static dict_element *dict;
  static int key_count;
  static int *keys;
  fill_keys(&keys, &key_count);
  fill_dict(&dict, &dict_count);
  auto funcname = [keys, dict] (element) {
    if (key_in_array(element->key, keys, key_count))
    ...
  };
  container_for_each(container, funcname);
  ...
}

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

По хардкору конкретно для Си можно сделать замыкания в виде генерируемой во время выполнения функции, которая будет вызываться без дополнительного контекста и сама уже добавлять захваченные переменные в скрытые параметры конечной вызываемой функции - примерно так делаются оконные функции в Win API.

Я надеюсь, что я вас убедил в том, что volatile - это бесполезный мусор в языке. В сухом остатке мы имеем:
- C89 привнес в язык прототипы функций, как единственную полезную новую фичу;
- Керниган и Ритчи ничерта не соображали и не соображают в проектировании языков программирования.

Теперь вернемся к исходному вопросу: зачем вообще комитеты существуют, потребляют кислород, и производят говно? Комитет не дал Си практически ничего, он не сделал язык лучше, он просто взял уже имеющиеся говеные практики и формализовал их.

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: http://www.cs.cmu.edu/~jbruce/humor/unix_hoax.html от qulinxao3

https://books.google.ru/books?id=ARdxDwAAQBAJ&pg=PA95&lpg=PA95

Привожу цитату Вирта:
«In its tow UNIX carried the language C, which had been explicitly designed to support the development of UNIX. Evidently, it was therefore at least attractive, if not even mandatory to use C for the development of applications running under UNIX, which acted like a Trojan horse for C»

То есть, Вирт называл UNIX троянским конем, а не киллер приложением.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

ну бллллллиииннн

посмотри тогда статью на которью цитирует в книжке - о взгляде на индустрию Вирта на дистанции 1960-2008(год статьи)

речь о backtracke -

есть чья та фраза «у масс осталась только одна вера(религия) - вера в прогресс»

всёж развитие(а но есть - и сингулярность таки уже происходит - мы нырнули за горизонт событий)

но приэтом всёж прогресс не настолько линеен что в каждый следующий момент каждый параметр не убывает

так и с программированием - Сишка - настолько удачен как мобильный ассемблер что благодаря реально талантливо-гениальности Томсона Макилроя Ритчи Оссаны и ваще той среды из которой выкатился unix - сделал на 20 лет ненужным многое что уже стало проникать из академии в индустрии в 1977+-

ваще ща есть возможность листать byte - c 1975 по нонешнее время

и просто видно как шла декрадация среднего читателя byte

по мере перехода перс компа из ниши гик-устройства в потребительский товар.

крч. Джоконда тем и прекрасна что не идеальна ..

Си не идеален и обладая кучей сравнительных недостатков смог.

qulinxao3 ★☆
() автор топика
Ответ на: комментарий от anonymous

альтернативные реализации ниасилили – в первую очередь, отладку с интроспекцией и препроцессор. поэтому развились упрощённые PL/M, PL/S и прочие subset G. из которых и получилось в итоге нечто годное, как тот же PL/I-KT реализация

Может быть, я открою для тебя секрет, но качество языка программирования определяется тем, насколько он прост, а не тем, насколько он сложен. Иначе бы все писали на машинных кодах. Обрезав под корень PL/I и внедрив в него идеи из алгола, Гари Килдал сделал практичный язык, на котором писал свой софт. Килдал был настоящим кодером, в отличие от плюшевых кодеров из комитета, создавшего PL/I.

но по-моему, эта фича – макросы – полезна, и ей есть место в toolchest программиста. если пользоваться ей грамотно, по уму. а не «ниасиливать макросы»
не нужно их бояться, это мощная фича языка. и метаязыка

Да, не нужно бояться фичи, которая убила Lisp, PL/I, и еще несколько подражающих им языков (вроде того же руби). Для справки, я напомню, что в той же Clojure метапрограммирование серьезно обрезано и написание собственных макросов рекомендуется только по крайней необходимости.

byko3y ★★★★
()
Ответ на: комментарий от anonymous

адой как продвинутым паскалем

Ада является настолько же продвинутым паскалем, насколько съеденная и переваренная курица является продвинутой версией живой курицы - да, какие-то отдельные исходные части там можно найти.

потому что опять же, язык должен быть полностью специфицирован, не должно быть никаких UB на уровне стандарта, язык-машины – и затем, реализации тоже

Проблема PL/I заключалась вообще не в попытке исключить UB. У алгола 60 почему-то никаких проблем с этим не было, и он стал самым влиятельным языком той эпохи.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

enjoy the club

То есть, Вирт называл UNIX троянским конем, а не киллер приложением.

Club America: текст:

I ride into your town on a big black trojan horse
I’m looking to have some fun
Some kind of trigger-happy intercourse
“Club America salutes you” says the girl on the door
“we accept all major lies
We love any kind of fraud
So go on in and enjoy…
Go on in and enjoy!!!”

I’m buying for my bright new friends
Blue Suzanne’s all round
And my mood is heavily pregnant…
Yeah you’re right
I couldn’t help but notice your icy blue eyes
They’ve been burning two holes in the sides of my head
Since the second I arrived

And it’s not too hard to guess from your stick-on stars
And your canary feather dress
Your hair in such a carefully careless mess
That you’re really trying very hard to impress

You’re such a wonderful person living a fabulous life
Sensational dazzling perfectly sized
Such a wonderful person living a fabulous life
Sharing it with me in Club America tonight…
...
anonymous
()
Ответ на: комментарий от anonymous

это не обязательно, и так у не только лишь всех. например, Евгений Зуев, в Interstone и их реализации компилятора С++ сделал семантическое дерево, а не синтаксическое – чуешь разницу? а она есть

Его AAST (Annotated AST) является, как он выражается, «нагруженной» производной AST, и все равно опирается на эту конструкцию. А условие было «вообще без рук».

byko3y ★★★★
()
Ответ на: комментарий от byko3y

volatile не подходит для многопоточных приложений. А значит зачем он вообще нужен? Правильно, для оптимизации кода, чтобы глобальные переменные стали как бы не глобальными, а глобально-кэшированными.

нет.

volatile нужен там, где состояние переменной определяется не абстрактной машиной С, а реальным железом.

olelookoe ★★★
()
Ответ на: комментарий от byko3y

Зачем были добавлены const и volatile - хорошо известно, описано, и мало связано с твоими простынями. Да, они плохо вписались в язык, да, они костыли.

ANSI с одной стороны, Страуструп с другой пытались сделать ЯП из того говна что родилось в AT&T и стихийно распространилось. Конечно, получилось только частично, но уже не в пример лучше того ужаса что был.

Что и какой комитет с тобой когда-то сделал - об этом стараюсь даже не думать.

anonymous
()
Ответ на: комментарий от anonymous

Хотя должен согласиться, что в каждом стандарте помимо безусловно полезных фич вводились и такие, которые убивают сам дух (c) языка. Например, абстрактная семантика в 89, VLA и strict aliasing в 99, _Generic в 11.

Есть также подозрение что в K&R была CFG, а CDG появилась из-за typedef в 89. Но это не точно.

anonymous
()
Ответ на: комментарий от anonymous

гиперграф из OpenCyc, например. только упрощённый, урезанный. или дерево конфигураций при суперкомпиляции Турчина (а не той, что в хаскелле) – где граф свёрнут ибо похожие конфигурации в дереве свёрнуты, мемоизированы при прогонке

Это абстрактные примеры, которые не относятся к сколь бы то ни было прикладному программированию. Почти все прикладные компиляторы/парсеры делаются на древовидных структурах.

byko3y ★★★★
()
Ответ на: комментарий от anonymous

из (1) не следует (2), а даже наоброт. (1) совершенно ортогонально (2)

Да. А еще трава зеленая, море - синее. Как это соотносится с моим утверждением о том, что на момент написания Си не существовало альтернатив для системного программирования?

byko3y ★★★★
()
Ответ на: комментарий от anonymous

диалект паскаля был описан ХЗ какой, и реализация комплиятора ХЗ какая. где не было модулей, unit, стандартной библиотеки, вообще ничего кроме readln/writeln. которые почему-то тоже предопределённые операторы, а не функции из стандартной библиотеки

Да, я именно об этом и написал. Но это было недолго, и уже в 1983 был турбо паскаль, который позволял клепать системщину. Разрыв довольно серьезный, 1970 => 1983 год. С другой стороны, первоистоковый Си и его компилятор сами были дермищем еще тем.

byko3y ★★★★
()
Ответ на: комментарий от anonymous

Ну и какая же альтернатива была, кроме асма?

форт.

Да, первый транслятор форта появился в 1971 году, на год раньше первого транслятора Си. Правда, все равно ниша активно пустовала еще в 1970 году. А там потом еще и PL/M появился в 1973.

byko3y ★★★★
()
Ответ на: комментарий от olelookoe

volatile нужен там, где состояние переменной определяется не абстрактной машиной С, а реальным железом

Да какая разница, драйверами, железом, сигналами, другим процессом, или чем угодно - все равно на фоне внеочередного исполения нет никакой гарантии, что значение, считанное из volatile ячейки предыдущей командой, действительно было таким до выполнения текущей команды. Более того, есть специальные команды/режимы процессора x86, которые гарантируют чтение именно из оперативной памяти, а не из кэша - они также не входят в понятие volatile, потому оно совершенно бесполезно для системного и многопоточного программирования.

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от anonymous

Зачем были добавлены const и volatile - хорошо известно, описано, и мало связано с твоими простынями

«Хорошо известно» - но не тебе, я правильно понимаю?

byko3y ★★★★
()
Ответ на: комментарий от byko3y

гм.

ладно, попробую еще раз.

volatile главным образом нужно тем людям, кто работает с реальным железом. например, для написания кода встраиваемых микроконтроллерных систем или портирования кода операционной системы на новую платформу.

не допустимо использовать volatile в целях достижения атомарности.

olelookoe ★★★
()
Ответ на: комментарий от byko3y

все равно на фоне внеочередного исполения нет никакой гарантии, что значение, считанное из volatile ячейки предыдущей командой, действительно было таким до выполнения текущей команды.

вот именно для этого и нужно volatile. чтобы не давать никаких гарантий. например, ты пишешь ведро ОС. и у тебя переменная изменяется в обработчике прерываний. эту переменную разумно сделать volatile, отключив тем самым компилятору любые гарантии что он может чего-то предполагать о её значении. она может изменяться как угодно, когда угодно, асинхронно. ибо ISR запустится когда угодно.

Более того, есть специальные команды/режимы процессора x86, которые гарантируют чтение именно из оперативной памяти, а не из кэша - они также не входят в понятие volatile, потому оно совершенно бесполезно для системного и многопоточного программирования.

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

anonymous
()
Ответ на: комментарий от byko3y

а вот const действительно костыль в С, который мало чего гарантирует. и const в С++ недалеко от него ушел. нетранзитивность константности против immutable в D, потенциальная возможность изменения константной переменой в другой нитке, гонки вокруг этого отсутствие которых компилятор не гарантирует, константный указатель и указатель на константу это два разных человека, указатель на константу не гарантирует невозможность изменения этой как бы константы через указатель, лол.

половина этих проблем разобрана подробнее в том слайде сравнения Си с PL/I. где другая идеология – описывать типы переменных по указателю тщательнее, а не сами указатели.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.