Pull to refresh

Comments 277

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

Основная причина отсутствие внимания к этой теме? Странно. А может отсутствие внимание и говорит как раз в защиту C! Кто мешает разрабатывать языки? Никто и ничто, разрабатывайте на здоровье. А время покажет станет кто-нибудь из них достойной заменой C.

Это Штирлиц. Сейсас будет драка.


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

Язык C жив до сих пор, потому что в своей области он самый удобный. Везде, где он был неудобен его уже заменили. Но код, непосредственно работающий на железе… Ну пусть пробуют. С прост в освоении и понимании. И, самое главное, самодостаточен. Libc и Posix в общем случае даже знать не надо чтобы писать код для микроконтроллера или процессора (будь то DSP или процессор общего назначения). Кросплатформенный ассемблер. И это ровно тот инструмент, который нужен разработчику. Просто не мешайте работать.

Инструмент вытащили далеко за области его применимости, и обнаружили — внезапно! — что он там плохо работает. И решили его заменить. Ну, да, писать либу размера и функциональности как OpenSSL на С — так себе начинание. Насчёт ядра Linux, например, уже нельзя сказать так уверенно. А что-то, что работает без ОС, "оживить" с помощью С — самое то.
Но ведь это нюансы, о которых мало кто думает. У меня многие знакомые программисты при слове "программировать" не вспоминают embedded даже с подсказкой. Типа "на железках дрова сами заводятся, как мыши в сене".

Проблема же не в том, что вы на нем работаете. Проблема очевидно в том, что зачастую получается плохо. Ну или хорошо — но очень медленно (или дорого, или оба сразу). В том, что иногда CVE на CVE сидит, и другим CVE погоняет. Если бы всего этого не наблюдалось в природе — никто бы про замену и не думал.
Нет, это не Штирлиц!


Хм. Ошибка выжившего?

Да ладно! А может наоборот — обилие CVE просто потому что код доступен для анализа и сделаны «best practice»? И стало просто отслеживать. Для остальных языков просто пока нет такого инструментария? Так это только вопрос времени…
Ну, не исключено. В смысле, я могу поверить, что хороших измерений, которые бы показали, что число багов в коде на С больше, чем скажем на Rust, сильно больше и они серьезнее — что этих измерений нет. Или они не показывают причины багов — то ли это свойство языка, то ли скажем показатель уровня квалификации пишущего (а это вообще сложно разделить, очень).

P.S. Минус не мой, если что. Может ваше мнение и неверное — но и мое в общем не более чем экспертная оценка, ни на чем более не основано.
Да нет же — это точно был Штирлиц!


А никто не может. И вообще людям свойственно ошибаться. А так как и код, и компиляторы пишут люди — ошибки неизбежны. У меня нет ни малейших сомнений в том, что рано или поздно они обнаружатся и в коде на Rust (и, весьма вероятно, в самом компиляторе или runtime-библиотеке). По другому не бывает. К этому надо просто спокойно относиться.

Для меня С основной инструмент. И используется он именно в самой низкоуровневой части. И Linux'овой, и FreeRTOS'ной и просто прямо по железу. Я так скажу — сегодня альтернатив ему нет. Нишевые задачи имеют нишевые решения, но пока только С обеспечивает возможность писать относительно быстрый, относительно безопасный, относительно переносимый и относительно хорошо поддерживаемый в будущем низкоуровневый код одновременно. Остальное компромися с явными перекосами в ту или иную сторону.

Нападки на него не новы. Пока выдерживает. А что до минусов — обычная история. Да, здесь в основном специалисты по «бизнес-логике приложений». Понятно, что нота ДО (С а буквенной записи) вызывает у них священный трепет, граничащий с непониманием. А количество ошибок с их колокольни говорит о проблемах языка. Их право. Но посмотрим что будет, когда их языки получат кодовую базу C. Я тоже человек и тоже могу быть не прав.

Знаете в чём проблема языка С? Что он близок к железу и если ты не знаешь как железо работает, то твой код ПОТЕНЦИАЛЬНО уязвимый. Многие современные языки пытаются быть дружелюным и прощать ошибки, но если в С/С++ ты накосячить с указателями тебе никто об этом не скажет ибо это всё работает и имеет какую-то логику.


Даже можно поразвлекаться.
Возьми вебмакаку которая никогда не трогала железо и посади её писать программы под DOS на ассемблере и ты узнаешь что никто не понимает как работает железо, будет кучу говнокода и копипаста ибо а как?
Тоже самое с FPGA, многие кто приходят кодить под это просто не могут понять что САПР просто выкинет его код на этапе компиляции и не скажет об этом если он не правильный.

Знаете, мне кажется не стоит. Не стоит бросаться терминами типа «вебмакака». В любой сфере есть гуру. И есть остальные. Вот это «остальные» как раз и включает в себя всю палитру — от «воцерковленных новорегов» решивших что наконец им открылся «неугасимый и все прощающий свет истинны» который надо отстаивать огнем и мечем от «грязных лап неверных», до реальных профессионалов, которые понимаю ограничения того или иного решения. Потому культура прежде всего. По крайней мере со стороны тех, кто может это себе позволить… А неофиты… Так их много, но они всегда разные. Потому как или любой неофит сразу начинает планомерной восхождение до «гуру» или… бесконечно находят «новый свет истинны» разворачивая орудия против того, что вчера еще было непогрешимо. Такие тоже нужны. Без них скучно.

А код без багов пишут только программеры-ангелочки в небесном ВЦ. Под ласковым взором главного тимлида. Остальные смертные всегда пишут с багами. Увы, не до всех эта простая истинна доходит.

На счёт багов, тут есть проблема, если мои сокомандникимогут писать под 2К в то и под 5К строк кода в день, то я методично отлаживаю дай бог 800. Ахахахха

UFO just landed and posted this here
Кухонный нож тоже очень опасен в неумелых руках, давайте все ножи заменим на пластиковые вилки. Если у человека руки ростут не из того места, то на каком бы языке он не программировал, все равно получится сами знаете что и язык Си тут не причем, это всего лишь остро заточенный кухонный нож!
UFO just landed and posted this here
Как автолюбитель не садится за руль Камаза (без обучения и практики вождения большегрузом), так и программисту-прикладнику незачем брать в руки «острый» инструмент под названием С/C++. Как утверждает Дядюшка Боб, недалёк тот день, когда программтистам начнут выдавать лицензии разрешающие или запрещающие использование тех или иных инструментов. Давайте не будем приближать это «счастливый» для нас момент, давайте выбирать инструмент по задаче и «по зубам».
UFO just landed and posted this here
Я бы все же по себе не мерил, прошлая дискуссия яркий пример.
UFO just landed and posted this here

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


Проще говоря, это как сравнить С с питоном. На питоне ты просто описал алгоритм анализа и он работает, а на С будь добр не забудь память контролировать и использовать определённые подходы в проектировании, чтоб переполнение и багов не получить.


Суть лишь в том что сейчас уже никто не работает с железом напрямую, я даже не видел ни одного программиста что бы использовал "гото" хотя с ним компилируемый код в местах становиться на пару сотен тактов быстрее, что бывает крайне критично. А кто нить пользуется "? :"? Это в любом случае генерит инструкцию условного присвоения что впринципе не влияет на производительность. Или может кто-то из кодеров использует дерективы компилятора чтоб "флоаты быстрее считались"?
Я не видел никого. Обычно все просто описывали алгоритмы на С, и в этом плане он уже старый.

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

Хм, прикольное замечание, спс учту на будущие

UFO just landed and posted this here

Ну я рад за вас что вы используете всё это, но я плаваю среди джунов и немного мидлов и там это всё редко юзается…


Я вообще писал на С только под одну платформу раньше и только недавно перешёл на компухтеры, ткчт без обид)


А на счёт кэша и TLB это 5 с половиной инструкций(шучу) где единственное доступное с ринга пользователя ток кэш. И там почти нету настроек а обычно что-то Типо "флаш кэш" и всё. Интриксы и вставки как раз оно


Ну и на счёт векторных инструкций всё неоднозначно, они вроде и нужны но и не нужны одновременно, тут трудно чего-то сказать
Хотя учитывают тенденцию что разница между 5МБ чистых бинарников и 1МБ не столь важна, то думаю да, С тут сосёт неплохо


Ну и про странный аргумент, он не в пользу кого-либо, а просто показывает разницу. Хочешь ручками оптимизировать, на те С, хочешь отдаться 4омпилятору и проч используй другие языки. Так я считаю

UFO just landed and posted this here
Нет, C и плюсы не дают максимальной производительности.
А никто не дает, только остальные еще хуже
UFO just landed and posted this here

Ну тип, не всё можно запихнуть в вектора, да и ещё сами векторные инструкции ни без выкрутасов. В районе шуточки что нужно MMX/SSE/AVX и у них разная нагрузка на конвейер, частоты работы и ширина команд. Вам какие вектора)?


Ну вообще я понял почему на лурке написано — "С/С++ ужасный и (вроде) новый функционал строиться на костылях, но увы ничего лучше ещё не придумали"


+о себе скажу что привык к verilog и не умею в "абстракции", мб потому пока ещё не наткнулся на проблемы в этом языке. Хотя работа с ссылками меня откровенно бесит… Ты просто указатель на память со сдвигом так почему я должен тасовать эти типы и писать кучу кода, капеец)))

UFO just landed and posted this here
Более того, С скрывает даже наличие векторных инструкций, и приходится либо использовать интринсики, либо ассемблерные вставки.


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

Вообще, никто и никогда не запрещает кодогенератору языка С использовать эти инструкции. Не делает он это отнюдь не потому что не может. Вспомните сколько вою было когда i386 убрали из поддерживаемых архитектур и сказали что теперь i686 минимум. Да и той уже нет. Потому 32-разрядные ARM'ы планомерно превращаются в тыкву следом за десктопными компьютерами. А прикладные программисты, радеющие за прямой доступ к векторным инструкциям и доступом к состоянию кеша… На фол последней надежды в футболе смахивает.

Что ж до «goto» и оператора "?", то по сути это вопрос стиля. И в целом тут не важно какой стиль использовать, важно не смешивать их друг с другом. Как минимум без крайней на то нужды. В случае «goto» и "?" это возможность избавится от лишних ступенек в идейно линейном коде. В этом смысле они хороши. И вполне себе используются. Впрочем, опять же — до понимания плюсов этих операторов надо дожить.

И конечно и безусловно — С (как и любой другой язык) невозможно выучить за 21 день. А предела совершенству нет. Потому чем дольше «точишь» мастерство, тем больше тонкостей применения тебе открывается. Другое дело, что желающих «точить мастерство» остается все меньше и меньше. В мире реальных вещей ценность «ручной работы» опущена ниже плинтуса. Это статусные и брендовые вещи. Пробраться в тот круг начав сегодня практически невозможно. В лучшем случае «сливки» снимут внуки. И то, если «дети» продолжат начато отцом. В программировании пока чуть лучше. Однажды созданная «цифровая» вещь дальше размножается методом почкования с минимальными затратами. Потому здесь еще эпизодически рождаются «штучные» вещи, которые выглядят реально классно на фоне «фабричных» аналогов.

В этом смысле С ушёл. Условному Mediatek нужно буквально пяток сотрудников для того чтобы создать U-Boot под свой новый условный Helio. И еще пяток для того чтоб адаптировать ядро. Все. 10 специалистов по низкоуровневому программированию обеспечат работой тысячи (если не десятки тысяч) прикладников. Начиная с условного Google (Android, PlayMarket, etc...) заканчивая авторами приложений и инди игр (а еще обеспечит работой всяких Youtube- и TikTok- блогеров). Странный парадокс в том, что эти «тысячи и десятки тысяч» разработчиков упорно учат тот самый десяток тому, что С плох и недостоин носить гордое звание языка программирования и вообще скоро умрет. Ну как тут не вспомнить знаменитое «миллионы не могут ошибаться»
Велика сила С(++) ровно в том, что он способен выдать это самое уникальное решение для уникальной задачи.

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


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

В случае с char* — именно что не может, потому что указатели на char могут алиаситься с любыми другими указателями.


Потому 32-разрядные ARM'ы планомерно превращаются в тыкву следом за десктопными компьютерами.

Как это следует из ваших слов?


Что ж до «goto» и оператора "?", то по сути это вопрос стиля.

Это не вопрос стиля, это вопрос лёгкости анализа кода, причём как статическими анализаторами. так и людьми.


В случае «goto» и "?" это возможность избавится от лишних ступенек в идейно линейном коде.

От лишних ступенек с ветвлениями избавляет оператор if, являющийся выражением. Но для C это, конечно, слишком сложно и революционно. Тернарный оператор не только плохо читается, но и ведёт к багам, потому что в C у него крайне неинтуитивный приоритет (в статьях той же PVS-Studio показывалось неоднократно, что это баги таки вызывало). Использование же goto в сишном коде — это либо хреновая замена break/continue, либо замена условных операторов для очистки выделенных ресурсов. В более продвинутых языках задача освобождения ресурсов возложена либо на деструкторы, либо на сборщик мусора и using/with/defer. И даже в C для этого есть GCC-изм attrubute((cleeanup)). Использование голого goto практически никогда не оправдано.


И конечно и безусловно — С (как и любой другой язык) невозможно выучить за 21 день. А предела совершенству нет. Потому чем дольше «точишь» мастерство, тем больше тонкостей применения тебе открывается.

Но в других языках как-то получается учить язык без изучения всё новых способов выстрелить себе в ногу.


Другое дело, что желающих «точить мастерство» остается все меньше и меньше.

Всё больше людей хотят просто программировать и при этом не держать в голове сотни условий, при которых происходит UB. Ну надо же!


В мире реальных вещей ценность «ручной работы» опущена ниже плинтуса. Это статусные и брендовые вещи.

Так ниже плинтуса или статусные?


В этом смысле С ушёл. Условному Mediatek нужно буквально пяток сотрудников для того чтобы создать U-Boot под свой новый условный Helio. И еще пяток для того чтоб адаптировать ядро.

Или условно два сотрудника с использованием условного Rust.


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

Напомните, сколько людей пилит компиляторы, без которых тот же U-Boot нахрен никому не сдался? Кажется, больше 10 человек. Сильно больше.


Странный парадокс в том, что эти «тысячи и десятки тысяч» разработчиков упорно учат тот самый десяток тому, что С плох и недостоин носить гордое звание языка программирования и вообще скоро умрет. Ну как тут не вспомнить знаменитое «миллионы не могут ошибаться»

Если вы всерьёз считаете C хорошим языком, то вы достойны всяческого порицания. Популярность C для низкоуровневого программирования — следствие более исторической случайности, нежели каких-то преимуществ C. И да, C нихрена не простой.

Но в других языках как-то получается учить язык без изучения всё новых способов выстрелить себе в ногу.


А теперь (только предельно честно) — как давно вы учили новый язык? Изучение любого языка начинается с отстреливания себе в ног и рук. И хорошо как ими ограничивается. Ибо чаще всего ломается мозг. А вот починить его до конца практически никогда не возможно. Потому и есть «профессиональная деформация» в связи с используемым языком.

Всё больше людей хотят просто программировать и при этом не держать в голове сотни условий...


Надо же. А меня-то учили, что любую задачу сначала должен решить программист в уме. Потом изложить методику ее решения на ПОНЯТНОМ МАШИНЕ языке и удостовериться в том, что машина ее решает верно в независимости от входных данных. Конечно, все больше людей хотят гребсти бабло лопатой корча из себя "великих программистов" (что бы это не значило). Только не надо в сложившейся ситуации винить язык.

Или условно два сотрудника с использованием условного Rust.


У вас есть машина времени? И как там в никогда? Нефть тоже вообще нигде не используется? Подшипники в электромобилях смазываются непосредственно электричеством? Или в вашем никогда повсеместно магнитная левитация и энергия исключительно из солнечных батарей? Пластики не используются? Деревья сразу вырастают в виде нужных компонентов?

Напомните, сколько людей пилит компиляторы, без которых тот же U-Boot нахрен никому не сдался


К проблеме курицы и яйца в компьютерах подход простой. Кто ближе к розетке того и тапки. U-Boot ближе.

Если вы всерьёз считаете C хорошим языком, то вы достойны всяческого порицания.


Так единственное о чем я прошу — не мешайте мне страдать. Это реально все.

P.S.
И да, C нихрена не простой.

Как говорит мой отец — просто с моста прыгнуть. Головой вниз. Над остальным надо работать.
UFO just landed and posted this here
Почему-то ноги целы и на месте.


А вы точно учили язык и продвинулись дальше «hello world»? Perl, TCL, VHDL, Verilog, Rust, да тот же Python мне изрядно попортили конечности. Правда все они были отложены ровно в тот момент, когда они добрались до мозга. Ибо ну его нафиг — меня кормит «хронический С головного мозга» и мне категорически нельзя допускать внеплановых «обRust'рений» других болезней.

Это работает только для тех задач, которые помещаются в уме.


Да ладно. А все методики типа сверху-вниз, ООП и прочее уже отменили?

То есть, когда я под AVR'ки писал, я был ближе (или круче, или фундаментальнее), чем gcc, которым я собирал свой код? Прикольно.


М… А вы компилятор потом непосредственно на AVR'ке запускали? Тогда да — круты и не слабы. Снимаю шляпу.

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


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

Жду… Сильно жду, когда наконец хоть кто-то из страдальцев начнет исправлять ту самую ситуацию когда С в основании стека технологий. Вот, тот же CodeRush (да, магия хабра специально не применена) говорит — тошнит от С, но переписывать UEFI на Rust никто не хочет. Почему? Потому как экономически (пока?) не выгодно. А в качестве pet-проекта… Хороший специалист по работе загружен так, что в качестве pet-проекта у него самый настоящий pet. И никак иначе. Потому бурлим. И пена идет. Но подождем пока все это доварится. Тогда и будем пробовать получившееся блюдо на вкус.
Потому бурлим. И пена идет. Но подождем пока все это доварится. Тогда и будем пробовать получившееся блюдо на вкус.

Когда вам станут очевидны преимущества Rust, поезд уже уйдёт.

О, да! Мне именно это говорили про Pascal, FoxPro, Delphy, C++, Perl, PHP, Python… Имя им легион. Теперь вот и Rust занял почетное место в этом строю.

Никогда не поздно начинать. Но преждевременная оптимизация — корень всех бед.
У меня в черновиках статья по глюкам Раст.
UFO just landed and posted this here
Как забавно ведет себя публика. Не, на самом деле — цирк с конями. За очевидный факт о том, что С уже много лет пытаются подвинуть другие языки прилетают минусы. За очевидный факт о том, что на С написано безумно много кода — минусы. За очевидный факт о том, что в исторической перспективе код на С оказывается самым живучим — минусы. Вот честно, временами складывается ощущение, что критическое мышление у народа наглухо отключено. Но ладно, это мелкие детали ни на что не влияющие. Та самая собака, которая лает. На тот самый караван, который идет.

Но в этом случае я не решаю задачу в уме! В этом случае я её решаю итеративно: сначала делаю первый набросок, потом заполняю детали, потом ещё…


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

И да, простите. Мне крайне сложно оценить наcколько «Hello, world!» код в вашем репозитарии. Потому просто верю.

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

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


Если человек страдает, но не предпринимает мер для устранения источника страдания, то он или мазохист или… страдания ничтожны в сравнении с получаемым удовольствием. Ту самую OpenSSL переписали на Rust. Вроде даже работает. Верю — народ страдал. А про ядро… Так мне уже сказали — очень толсто.

Математически выверенный устойчивый код на контроллерах. Ну да, за этим будущее. Только до этого будущего еще большой путь. Сначала должен появиться инструментарий и реальные требования для контроллеров ответственной сферы. Космос, медицина, энергетика, транспорт… Потом, когда оно докажет свою целесообразность и состоятельность — промышленность и малая автоматизация. И только после этого всякие домашние поделки типа ардуино и прочих конструкторов.

Я же не имею ничего против эволюции. Я против революции. Когда пусть и хорошее решение, но навязывается «огнем и мечом». Впрочем, помня возрастной срез аудитории хабра не удивительно что здесь как раз сторонники революционных мер. «До основания, а затем. Мы наш, мы новый мир постоим.» Только вот не дам я «до основания» раньше, чем другой мир появится. И, к счастью, не только я.
UFO just landed and posted this here
Да. Да. Не уверен. Не владею информацией о живой кодовой базе на Cobol'е. На всякий случай не спорю. И дело не в минусах или плюсах. Дело в отношении. Как же много людей которые мало того, что себе не верят. Страшно за то, что вместо собственного развития и понимания они готовы отдать все на откуп машине. Впрочем, жизнь меняется…

Не начинает решать, а решает. Целиком. «Решить» — совершенная форма.


И все же здесь я вынужден настаивать на своей формулировке. Именно решить. Именно совершенная форма. Весь верхний (а лучше несколько верхних) слоев если мы говорим о сверху-вниз.

Только этот путь не пройдётся сам, его надо активно проходить.


Так я ж не предлагаю стоять на месте или двигаться назад. Я с интересом наблюдаю за развитием того же Rast'а. Вопрос в том, что подавляющее большинство собеседников похожи на моего старшего сына. Тот тоже подходит с вопросом «папа, а давай сделаем...» подразумевая «папа сделай, а я в лучшем случае рядом постою». Во всяком случае когда дело касается системного программирования. А уж как хотите — возглавлять крестовый поход против С я точно не буду. Пока есть заказчики на код на С (создание, поддержка) я буду писать на нем. Ибо это тот инструмент, навык пользования которым я точил и продолжаю точить. Вот не будет — тогда буду думать. И то, скорее о гидропонной ферме и прудике с карпами в деревне, чем об освоении чего-то диаметрально отличающегося.
UFO just landed and posted this here
Почему всё? Только проверку того, что они правы.


Хорошо, а что остается от того все?

Хотя лично у меня нередко бывает exploratory programming, когда я не до конца понимаю проблему, и открываю редактор и начинаю что-то в нём писать-играться, чтобы лучше эту самую проблему понять.


Подход художника vs подход скульптора. Под многими даже очень известными картинами реставраторы находят второй и временами даже третий слой. Начал рисовать. Не понравилось. Закрасил и переделал. Некоторые картины вообще откровенно поверх неудачных работ написаны. Скульптору так нельзя. Уж если отколол, то отколол.

Уверены что скульптора камнетеса хотите заменить на 3D-принтеры просто потому что у тех возможности «накосячить» меньше и повторяемость результата лучше? Мало того — молото с зубилом запретить, скульптуру объявить лженаукой и изгнать из учебных заведений? Есть же море альтернатив. Литье, ковка, лепка, рисование, те же 3D принтеры.
UFO just landed and posted this here
Построение решения задачи.


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

Отличная аналогия! Никто вас за язык не тянул :]


Превосходно. Только настоящий инженер сначала эскиз рисует. И до реально «железного» изделия обычно бывает множество прототипов. Потому как изделие (особенно тщательно обсчитанное, из выверенного материала, с проверкой на полости и пустоты) стоит денег. Да и в массы оно идет уже не литьем, а ковкой, гибкой, фрезерованием (что мало отличается от скульптуры) и имеет очень много расхождений с первым высчитанным экземпляром. И изделия все равно (как минимум выборочно) проходят натурные испытания.

Да, конечно, механика не IT. Детали не размножаются простым копированием. Но если деталь можно сделать ковкой или вырезкой — будьте уверенны никто ее не будет печать на 3D принтере.

Про «не скульпторов зовут». Есть такая профессия — макетчик. Это специалист по деланию МАКЕТА изделия из любимых подручных материалов. Кабели — веревки, корпуса — моченые газеты, мелкие детали — пластилин. Незаменимый человек на начальном этапе — проектирования. Когда эмоции бурлят, у каждого свое видение готового изделия. И надо сравнить разные варианты и выбрать самый удобный. И уж только с него инженер начинает что-то считать. А еще с него можно начать готовить кофры, чехлы, встраивать куда-то. Если все это делать 3D принтером то никуда не успеешь и денег не напасешься. Даже автомобили делают из макетной глины. Да и массовое производство… Впрочем, я про него уже писал.

Так что не надо мне рассказывать про идеальный мир, сделанный инженерами в SolidWorks. Как и про идеальный мир, где все вообще написано на абсолютно безопасных языках. Я, знаете ли, не хочу чтоб меня «умная дверь» из дома не выпускала на том лишь основании, что без ее надзора я прямо в коридоре споткнусь и коленку расшибу.
UFO just landed and posted this here
Тогда к чему вы вспомнили про 3D-принтеры?


Так все же просто. Всегда есть два подхода. Взять заготовку и отсечь все лишнее и взять ничего и «слепить» нечто. До сих пор в основном главенствовал (и главенствует) первый. Но хайп вокруг вторых приводит к тому, что они начинаю применяться где только можно. Местами сильно мешаясь и наоборот замедляя работу. Макет из папье-маше опытный макетчик сделает быстрее и точнее чем 3D распечатает 3D принтер. Часть задач на С надежно решить получится быстрее и не менее качественно, чем описывать ради этого все особенности преобразования типов в них на том жe Rust'е. Я бунтую против Вашего «требую чтоб везде». Я не бунтую против инструментов.

А можно я всё же буду?


Можно. Только получите в ответ провокационный вопрос. А на чем написан SolidWorks? Как вам может нравиться код, написанный на «рассово не чистых» языках?

И потом. В расчетных библиотеках того же Solid'а встречаются ошибки. И ни одна сертификационная лаборатория не поставит штампик только на основании того, что мы «посчитали в Solid'е». А если конечное решение все равно за сертифицирующим центром, то зачем навязывать всем именно Solid. Есть альтернативы. AutoCAD, тот же Компас, кульман в конце-концов. Почему вы считаете себя в праве ограничивать разработчика в выборе инструмента? Более того — вот уже вторую неделю упорно доказывать правоту такого подхода? Ведь весь сыр бор исключительно по этой причине. Или личная неприязнь и предвзятое мнение непосредственно к языку С.
UFO just landed and posted this here
Это очень сомнительный для меня тезис, но не думаю, что его обсуждение будет конструктивным.


Можно подумать во всем этом обсуждении есть хоть один не сомнительный тезис. Да и в целом обсуждение конструктивностью не блещет. И это было просто очевидно с самого начала.

Мы же не обсуждаем, на чём написаны coq, agda или idris?


Значит ядро и драйвера осуждаем, а остальное нет. Впрочем, да — конструктивности тут ждать не приходится.

Если этот опытный макетчик стоит как стопицот 3D-принтеров, то его услуги будут не очень востребованы.


Это полит-экономический вопрос. Инженеры их (обычно) сторонятся. Впрочем, имею честь наблюдать результат Solid + 3D принтер сейчас vs приходящий макетчик + дизайнер за кульманом некоторое время назад. Я не конструктор. Но меня всегда зовут на обсуждения конструктивов изделия (причины вынесем за скобки, сказав для простоты что доверяют моему инженерному чутью). Так вот — корпус на принтере получается реально красивым только чистовой. Очень долго и очень дорого. Оперативные корпуса… Нет, «бумажные» однозначно были лучше. И уж точно по совокупности не дороже. А те наработки используются до сих пор, незначительно дотачиваясь под современные. Не родило поколение фанатов 3D принтеров ничего принципиально нового. Впрочем… Возможно их полет фантазии просто сдерживали… И как раз последствия пандемии наконец смогут помочь им показать себя во всей красе… Не ругаю я коллег. А уж тех, с которыми работаю и подавно.

Впрочем, есть свои плюсы у печатных. На них проще оценить финальную конструкцию. Реальные платы, разъемы, дисплей, шлейфы… Тут не так важна кривость корпуса, как четкое понимание — состыкуются компоненты или нет. Будет шлейф перекручен или нет. Есть необходимые зазоры или упираемся. Но все равно — будь решение за мной я бы начинал с «бумаги».

Но блин — каждому инструменту свое применение. Это единственный конструктив из всей этой темы. Есть спрос на С — будет С. Нет спроса на С — будет что-то другое. Мне хватает заказчиков, которые не так сильно обеспокоены RCE и прочими неприятностями. Хотя… Не скажу что подход когда безопасность решения базируется лишь на том, что «противник не знает систему» мне нравится. И я всячески пытаюсь убедить таких заказчиков в том, что так нельзя. Но и фанатично вкачивать ресурсы в безопасность ради безопасности и неудобства пользования изделием… Так себе удовольствие.
Остался один момент — а есть уверенность, что ответственную задачу можно поручать троечнику, который с трудом понимает граничные для нее условия? Или что не еще хуже понимает, но не знает как обойтись без «умной машины», которая за него все посчитает?
Так а вы что бы выбрали, поручить такую задачу:
— троечнику + стреляющий по ногам ЯП;
— троечнику + безопасный ЯП?
— Ты сразу спать пойдешь или сначала зубы почистишь?
Детский сад право слово.

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

Впрочем, успокойтесь вы уже. Я же сказал — OpenSSL на здоровье. Пусть хоть двоечники переписывают. Нет тут особых требований по скорости — безопасность перевешивает. И себе выбирайте язык, который вам комфортнее. И забирайте от меня часть работы.

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

Скажите, а вы спеллчекером пользуетесь?

В комментариях обычно нет. А это что-то меняет? Мысль осталась непонятой?

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

Где я чего предлагаю? Еще раз — я не против прогресса. Если кто-то готов заменить старичка С — милости просим.

Но в целом идея именно такая. Spell check — это компилятор, а уж meaning checks — это строго за человеком. Во всяком случае в тех местах, где производительность не перевешивается безопасностью (хоть safety, хоть security).
Если человек не способен писать грамотно без спеллчекера, то это… ну скажем так, навевает смутные подозрения. В случае с программистом — ещё и грозит смутными последствиями.
Популярность C для низкоуровневого программирования — следствие более исторической случайности, нежели каких-то преимуществ C.
Wtf?
А что, есть реальный выбор для эмбеддед, ну хотя бы сейчас?

Ну и исторический взгляд тоже не помешает. На момент создания С +- 5лет

P.S Или может в области ядер операционных систем случился какой то прорыв, а я пропустил?
есть реальный выбор для эмбеддед, ну хотя бы сейчас
Плюсы, Ада, Forth, подмножество Rust. Форт поменьше и пошустрее, Раст побольше и помедленнее, Ада с плюсами на уровне С.
Ну и исторический взгляд тоже не помешает
Если смотреть просто по списку, то выбор был: Forth, Simula, PL. А какая на самом деле была известность, доступность документации и эффективность работы компилятора — это у олдфагов надо спрашивать, кто застал.
UFO just landed and posted this here
Ну я не спорю, что это все работает. Но реальная кодовая база сравнительно мала, и вендоры часто поставляют свои SDK на каком-нибудь С99. И даже если используются плюсы, то это чаще что-то старое и C style. Бегло глянул NRF — gnu++98 / C99.
In the wild я всё это, кроме Раста, банально видел: чистый С, конечно, чаще, Форт наравне с чистым ассемблером, аду пару раз в стрёмном оборудовании за многоденег.
Очень конечно смешно, советовать по форумам… Особенно то, что не видел даже по причине позднерождения, вроде Симулы. Ну или форта, которому нужна фортмашина для конкретного железа.

Занесу тебя в игнор.
Не понимаю, почему стоит обижаться на обоснованный ответ на вопрос. Форту, конечно, нужна форт-машина, но и в компилятор надо целевую архитектуру ручками добавлять.
Если вы всерьез считаете, что есть какой-то ЯП лучше С, я вам сочувствую!
А если вы считаете этим ЯПом педеrust, то я вообще в шоке!
UFO just landed and posted this here
У вас как-то очень много отсылок к прикладным программистам с коннотациями, которые я не до конца улавливаю


Конечно. Потому как прикладное программирование много шире системного. Потому нет к нему единого отношения. Однако, в подавляющем большинстве случаев для прикладного ПО характерен ответ в стиле «Подумаешь тормозит! Завтра будет новое поколение процессоров и еще больше памяти и будет летать.» Именно этот ответ я получил в ответ на недоумение от факта запуска на Marvell PXA320 с носителем в виде SD карточки под Linux postgreeSQL. Особый шик в том, что это самое «железо» для них делал я (тогда еще сам). И вполне себе отдавал отчет в том, что ни завтра, ни послезавтра я им не выкачу систему, которая на подобное способна. В любом случае системщики себе такое поведение позволить не могут вообще никогда. Собственно, если хорошо подумать, то именно возможность именно такого отношения к задаче делит мир на прикладников (тех, кто может) и системщиков (кто не может).

Точить мастерство листания и интерпретации стандарта, чтобы понимать, UB передо мной или не UB, можно ли код коммитить...


Знаете, вот это именно та часть по которой уже я не понимаю Вас. Временами мне кажется что я разговариваю не с разработчиком, а с предвзятым критиком. А с такими, как религиозными фанатиками…

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


Слушайте, а мы точно про С сейчас говорим? В самом деле. Даже код 20-летней давности (за который немного стыдно) совершенно без проблем компилируется современными компиляторами и выдает рабочий бинарь. По сути это просто возвращает нас к тому самому моменту про оптимизатор. Не надо оставлять свободы оптимизатору и код останется рабочим навсегда. А умение так писать… Ну да, оно точится. И без фокусировки на инструменте (вместо расширения по фронтам и осваивания всего и вся) эта задача нерешаема.

Отчасти по этой причине я посмотрел на Rust и… отложил его в сторонку. На моей памяти С «воевал» с ассемблером не один десяток лет (попутно отбиваясь от Pascal'я и Basic'а). Вполне достаточно для жизни поколения разработчиков. Пусть молодые разработчики осваивает Rust. Возможно, действительно через некоторое время появится шикарная возможность сменить пяток наСильников на пару Rust'оманов.

К слову о реально важном. Ау, фанаты Rust! Фиг с ним с ядром — сделайте аналог U-Boot'а для Cortex-A. У этой задачи нет жестких требований по размеру, она не висит в памяти резидентно и весьма востребована. Ибо barabox тоже не сказать что совсем уж торт. У вас сегодня для этого все есть.
UFO just landed and posted this here
С -O0, небось? Новые компиляторы приносят новые оптимизации, основываясь на новых способах интерпретировать UB.


-O size для контроллеров. Для ПК у меня значимых абсолютно своих проектов нет, но насколько мне известно тот же Linux и U-Boot собирается отнюдь не -O 0.

Впрочем, для сборки ядра 2.6.35 нужен gcc не выше (не помню) и bunutils не выше (тоже не помню). Так что я не возьмусь утверждать, что в Ваших словах правды нет совсем. Но это тема уже другого разговора. Где тема недостатков языка С уже не будет иметь такой существенной роли.

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


Да ешкин же кот. Конечно. Безусловно. Абсолютно верно. И я разве где-нить выступал против?

«Вагонные споры последнее дело, когда больше нечего пить» (с) Макаревич

Причина ж не в этом. И спорим мы с вами не об этом. Ведь весь наш спор идет по сути вокруг одной простой идеи. Вы ратуете за то, что компилятор не должен позволять «говнокодить». Я ратую за то, что разработчик не должен позволять себе «говнокодить». Вы говорите раз компилятор позволяет разработчик обязательно наговнокодит. Я говорю что фантазия разработчика сильно шире и всегда найдутся индивидумы которые обойдут любые ограничения компилятора и все равно наговнокодят. Вы соглашаетесь и ратуете за усиление контроля со стороны компилятора. Я соглашаюсь и ратую за усиление воспитания программиста. И… Опять все сначала.

"… и каждый пошел своею дорогой, а поезд пошел своей." (с) Он же и там же.
Вы ратуете за то, что компилятор не должен позволять «говнокодить». Я ратую за то, что разработчик не должен позволять себе «говнокодить»
Так в статье про то, каким должен быть хороший ЯП нельзя надеяться, что косяки языка будут компенсированы преподавателями computer science.
Несогласных со статьей расстреливают сразу? Демократию отменили? Огласите список непогрешимых авторов и генеральных идей.

Я уже писал. Личное дело каждого в какого бога верить.
Несогласных со статьей расстреливают сразу?
чтобы их не расстреливали они сначала должны предоставить веские причины своей точки зрения, ибо довод «просто пишите код качественнее» не всегда прокатывает в нашем жестоком мире.
Я бы послушал веское доказательство той точки зрения, которая опровергает АКСИОМУ «просто пишите код качественнее». Есть желающие совершить такое?
Так аксиома «просто пишите код качественнее» не противоречит другой аксиоме «ЯП должен брать на себя максимум бездумной/механической работы человека и оставлять последнему только выполнение бизнес-задач и воплощение требуемой логики».

Первой аксиоме учат в учебных заведениях (ну и жизнь тоже учит).
А второй должны следовать разработчики очередного ЯП.
Отлично. Но при чем здесь С? Меняйте его современными языками в рамках решения своих «бизнес-задач» и «воплощения требуемой логики» (что бы это не значило). А то [синоним слова говорить] каждый может. А как замените расскажете как было плохо и как стало хорошо (или наоборот). А то смахивает на дележку шкуры неубитого медведя.
То есть вы всегда сначала делаете, а потом думаете, почему так получилось? Или вы все же сначала обдумываете преимущества и недостатки разных подходов, обсуждаете их с другими и только потом приходите к выводу «как делать»?
То есть вы всегда сначала делаете, а потом думаете, почему так получилось?


Так кто из нас кричит, что С несовременная, дурно пахнущая субстанция требующая срочной замены повсеместно? Разве я?

Я 30 лет назад принял решение и стал электронщиком (схемотехником). С серьезным уклоном в цифровую технику. 20 лет назад понял, что схемотехник вот-вот переплюнет ювелира, а я никак не могу своими руками менять BGA чипы обычным паяльником (да и компоненты типоразмера 0201 мне уже не по силам). Потому переквалифицировался в программиста. Системного. Сначала Assembler, затем C. И до сих пор именно этими знаниями решаю те самые «бизнес-задачи» и «воплощаю требуемую логику» (что бы это не значило). Там где можно. А там где нельзя упорно отговариваю заказчика и уступаю место тем, кто по моему мнению с данной задачей справится лучше. Потому и говорю: «Считаете что можете заменить С в конкретном месте — меняйте. Нет — не [синоним слову говорите] и не мешайте работать.» С OpenSSL же получилось (получается?).

Да, я сначала думаю, потом делаю, потом снова думаю и снова делаю. И эта цепочка прерывается ровно в тот момент, когда заказчик говорит — достаточно. Результат меня устраивает.

Переформулируйте вопрос.
Переформулируйте вопрос
Я думаю, что вы прекрасно сами все поняли. Вот только я одного не пойму, в чем вы упрекаете людей, которые хотят разобраться в преимуществах и недостатках конкретной технологии? А также в возможных альтернативных вариантах (которых может еще и нет).
В предвзятом отношении (ну и слюной брызгать поменьше).
А можно ссылку на чей-то предвзятый комментарий (а не просто с оценочным суждением)?
С OpenSSL же получилось (получается?).
отличный пример библиотеки, печально известной за обилие багов, использование которой вызывает PTSD у бывалых кодеров. Говорят кстати алгоритмы шифрования переписали на безопасном расте.
OpenSSL, LibreSSL, rust-openssl. Пришло время. И слава богу. Мне остается только пожелать успехов.
Впрочем, я тут опять слегка накосячил. Думал все же о «хвойных». О Sequoia-PGP.
Но в любом случае — и там и там безоговорочно поле Rust'а. И славненько. Пусть так и будет.
это слабо помогло=)
моя робкая попытка хотя бы скомпилироватьть раст версию зафейлилась (исходники тут)
Если перестараться с «хорошестью» языка, то задачи разделятся на решаемые однозначно и в пару строк средствами языка и на те, для решения которых нужно дёргать библиотеку, написанную на другом языке. Этакий APL 2.0.
UFO just landed and posted this here
Далеко берёте...


Да просто вспомнилось. Впрочем, радетелям «правильных» языков могу порекомендовать собрать на Ubuntu 20.04 LTS хотя бы AOSP 9.0. И поплеваться с питона. Для меня это вполне свежий пример, показывающий что на определенном этапе развития языка подобные проблемы неизбежны.

для говнокодинга достаточно ограниченной внимательности.


О да. Этого всегда достаточно. Было. Есть. И будет. При чем чем больше доверия автоматике, тем больше. Именно по этой причине натурные тесты в критических и закритических условиях всегда крайне желательны (а в некоторых областях обязательны).
UFO just landed and posted this here
Хм… А можно примеры из смежных отраслей?

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

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

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

Лично я был бы тоже против, если бы на моноколёсах перевозили ядерные боеголовки, как это происходит сейчас.

UFO just landed and posted this here
И тренд на то, чтобы добавлять больше страхующих систем, а не удерживать внимание.


ASLR — да. Неисполнимый стек — да. Тотальный контроль — категорически нет.

Люди, которые ими пользуются, скорее себя угробят, чем других


Владельцы транспортных контор, в парке которых КАМАЗы (или в Вашем случае Freightliner) одобряют. Автобусы и такси тоже не представляют абсолютно никакой опасности для окружающих. А уж свободное хранение (а паче ношение) оружия — вообще абсолютно безопасное затея для окружающих.

Вам жить не страшно? Столько опасностей вокруг. Может в сравнении с ними очередное переполнение буфера в ядре просто безделица?

Вы, кстати, ведь в курсе, что ваши права по полётам сильно ограничены, если у вас нет ADS-B?


Я не знаток авиационных систем. Но в любом случае — это информационная система. Она не перехватывает управление полетом и не устраняет главную причину авиакатастороф. Да, я о человеке.
UFO just landed and posted this here
Поэтому есть такая тема… На получение license to carry надо сдать экзамен.


Хм… А ответственный код значит можно писать не имея на это право?

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


Как вы говорите — да на здоровье. Как хобби или исскусство. И лучше спрятать в запасники музея для специалистов, чтоб не дай бог дети не увидели.
UFO just landed and posted this here
всё не нужно, если просто писать код аккуратно, без багов и дырок.


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

Другое дело, что в последнее время стало мало выполнять непосредственно задачу, поставленную перед кодом. Все эти хакеры, и прочие local privileges escalation и remote code execution… И вот это действительно проблема. И у меня нет хорошего пути решения для этой проблемы. Но мне кажется (больше того — я уверен) что решаться она должна не сменой инструмента, а повышением образованности разработчиков. Скорее всего это должно привести к тому, что сильно больше будет специализация разработчика, а популярные нынче варианты «сегодня AVR, завтра front-end, послезавтра Java» потихоньку должны умереть. Ибо именно это не что иное как анархия. В которой некоторое количество сообщений назад обвиняли меня и язык С.
Ну да. Александреску доточился и свалил в D. Мейерс доточился и свалил из индустрии вообще. Я, конечно, не Мейерс и уж тем более не Александреску, но я тоже доточился. Точить мастерство листания и интерпретации стандарта, чтобы понимать, UB передо мной или не UB, можно ли код коммитить, или я закладываю бомбу, которая может взорваться через пару апгрейдов компилятора, как-то стало всё меньше желания.
Надо не путать между «доточился» и «сточился» [в попытках понять].

Насчет UB я вообще не понимаю. Практики делают как им надо, остальные ноют про УБ.
Здесь я вижу прямую аналогию с ПДД, когда новички ноют про сложность и непонимание, а остальные просто ездят с минимум проблем.
UFO just landed and posted this here
UB это ошибка программера.

Нечего на зеркало пенять.
UFO just landed and posted this here
А о чем мы говорим?

Если про твой последний пример — то там явно перемудрствование на ровном месте.

А если ни о чем — то есть поговорка про «сдуру» и «сломать».
UFO just landed and posted this here
При чем тут плюсы? Статья про Си вообще-то, это совсем другой язык. Плюсы действительно переусложнены и с каждым новым стандартом туда впиливают все больше и больше возможностей выстрелить в ногу. А Си — очень простой и компактный язык. И изучить его можно если не за 21 день — то за пару месяцев точно.
UFO just landed and posted this here
UFO just landed and posted this here

а я не согласен.
да, владение C можно улучшать бесконечно.


но «выучить» (понять как оно устроено) мне в подростковом возрасте хватило несколько дней чтения k&r. без практики (ибо не на чем было). потому что если знаешь ассемблер, то читаешь k&r и понимаешь почему было так сделано, а логичные вещи и изучаются легко.


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

UFO just landed and posted this here
… У которого обе грани заточены. И рукоятки нет. И оба конца острые...


Простите. Не смог удержаться.
image

Да, С именно такой. Только вот обматывать его тряпочкой, или резать лук… Не, ну можно конечно. Но лучше перерезать себе все руки, но наработать инстинкты безопасного поведения и перестать его бояться бояться и начать оттачивать умение им пользоваться.

На самом деле вопрос-то очень интересный. Я корнями в деревне. По детству, в самых дальних закоулках чердоков находил иконно русскую косу-горбушу. И даже доставал, точил и косить пробовал. Но старички смотрели, хмыкали и говорили — не майся ерундой. Вот тебе нормальная коса (коса литовка). И да, вот ее я освоил. В совершенстве. Площадь, обкосить вокруг кустов, неровная поверхность — все равно. Все будет обкошено. Да так, что травы останется ровно 1,5 сантиметра. Сегодня молодежи уже я хмыкаю и говорю не майтесь ерундой — есть же триммер. И да, триммер быстрее и удобнее. Усталости сильно меньше. Но сам почти всегда достаю привычную литовку. Как так? А вот так. Только ей у меня получается сделать хорошо. После триммера волны. Где-то дерн цепляет, где-то недорезает. А к литовочке настолько привыкла рука, что ей плохо сделать ну никак не получится.

К чему весь этот спич? Горбуша — ассемблер с макросами, ибо без макросов серп получится (тоже к слову умею). Литовка — это С. А триммер — все что выше и лучше. Косить гектары даже триммером так себе идея. Тут комбайн нужен. Обкосить канаву литовкой тоже не лучшая идея. Камни, рытвины. Уж лучше триммер. А вот скосить «английский газон» перед домом… Ну ка его, этот триммер. Лучше литовочку. Чтоб результат глаз радовал. Да травку вывезти, а не на месте гнить оставить (привет автоматическим сборщикам мусора). Больше того — в кусту смородины сорняки покосить — так тут и литовки много будет. Тут в сарае серп лежит.

Рачительный хозяин любому инструменту применение найдет. Главное понимать где границы применимости.

Этот комментарий можно сократить до двух слов: "Сперва добейся"

Ну что Вы. Совсем нет. 0xd34df00d мне хорошо знаком по комментариям в других темах. Уж ему-то точно даже мысли нет отвечать в таком ключе. Как и другим оппонентам в этой теме.

Свое отношение я выразил первым комментарием. Могу повторить. Обсуждать недостатки языка С имеет смысл с теми, кто им пользуется на регулярной основе. Только эти люди знают о нем все. Но ведь они, как правило, и не спорят. Больше того — даже не ввязываются. «Собака лает — караван идет».

Те же, кто «когда-то подходил к этому снаряду», но по тем или иным причинам не стал им пользоваться как раз и превращаются в ярых противников. Можно сказать что в этот раз еще культурно. Обычно такие споры злее. Массивы и указатели. Указатели на функции. Двойные, тройные указатели. Размерность стандартных типов. time_t разного размера. Опять же errno. Имя им легион. В принципе понятно, что язык С давно требует как минимум глубокой модернизации. Но провести эту модернизацию упорно пытаются со времен D и C++. Местами успешно. В свое время в вебе perl легко подвинул С++ — он был банально удобнее.

Сможет ли кто-то из ныне существующих подвинуть C в низкоуровневом программировании? Не знаю. Хабр любит Rust. Мне он не понравился. Я переборол первое впечатление и попробовал его в деле. Нет. Не нравится. Синтаксис. Необходимость переделывания «заголовочных» файлов железок. Итоговый двоичный код. Возможно, это наведенное — следствие плохого первого впечатления. Но для меня показатель еще и в другом. Где работа Rust community? Почему до сих пор на github'е нет синхронизируемого в ванилью репозитария ядра Linux (с переписанными важными частями системы)? Почему нет значимых попыток переписать (U)EFI на Rust? Все ждут пока кто-то за них это сделает? Ну хорошо, пусть ждут. "… Караван идет". А то, что на Хабре очень много решительно настроенных противников С для меня давно не новость. В том же первом комментарии было написано «Это Штирлиц. Сейчас будет драка.» Это было слишком очевидно.
Почему до сих пор на github'е нет синхронизируемого в ванилью репозитария ядра Linux (с переписанными важными частями системы)?

Слишком толсто, попробуйте ещё раз.

UFO just landed and posted this here
Вьедливы Вы. Но, как всегда справедливы. Конечно. Те, кто пользовался довольно долго (есть успешные проекты в продукте, с количеством в штуках порядка нескольких десятков тысяч). Те, кто сопровождал свой код на С несколько лет, но сегодня сменил род деятельности. Да и вообще — я, вроде, никому рот не затыкаю. В этой теме я скорее «адвокат дьявола». А прокуроров хватает.

Что до мастеров комбика C/C++… Не хочу высказываться на эту тему. С моей колокольни это принципиально разные языки. Их генетический код разошелся очень давно. Потому я просто не знаком с задачами где это надо. Знаю где нужен C++. Знаю где нужен C. Но с трудом могу представить себе задачу, в которой один разработчик должен ответственно использовать оба этих инструмента. И в любом случае не хочу оказаться на месте этого самого разработчика.
UFO just landed and posted this here
Так ведь весь спич с моей стороны ровно об этом. То, что для C++ страшная трагедия, для классического C чуть ли не Killer-фича. У меня нет никаких проблем контролировать переполнение (там, где надо — но мне ни разу надо не было). А возможность разыменовывания любого указателя (а равно арифметика указателей) позволяет весьма эффективно управлять аппаратурой.

Да, конечно — очень часто это игра на грани. Конечно, довольно часто она приводит к очень нехорошим последствиям. Конечно, надо думать как от подобного защититься. Я ж против этого ничего не имею. Беда лишь в том, что любое современное решение это очень плохой компромис. Даже в сравнении со старым и проблемным С.

Впрочем, справедливости ради стоит заметить — сегодня объем кода, производимого компиляторами С едва ли подберется к 1% от кода с других языков. И это соотношение весьма внушительно. Можно сколько угодно кричать о том, что прочность цепи это прочность самого слабого звена. Можно пенять на С говоря смотрите — CVE на CVE сидит и CVE погоняет. Но где хоть какие-то гарантии того, что в оставшихся 99% дырок меньше. Просто нашему 1% уделяется самое пристальное внимание. В первую очередь именно по причине того, что типовые заморочки очень хорошо известны и довольно легко обнаруживаемы.

Согласен — ситуация не нормальная. Только вот обвинить язык С в том, что именно на нем лежит вся вина… Что он провоцирует написание кривого кода… Что он генетически неправильный… Да ну, нафиг. По мне это перекладывание ответственности с программиста на язык… Не правильно это как-то. Впрочем, оценка комментариев как раз говорит о том, что мнение это на хабре не популярно. И я теряюсь в догадках, популярно ли ему обратное. Что любая кухарка должна уметь управлять государством писать любые программы, а уважающий себя язык должен ей в этом помогать, четко и однозначно указывая на проблемы. Этакая диктатура языка, вплоть до исправления алгоритма решения. Нет уж. Мне больше по душе демократия С.
У меня нет никаких проблем контролировать переполнение

Интересно, как вы это делали, если переполнение знаковых целых в C — неопределённое поведение.


А возможность разыменовывания любого указателя (а равно арифметика указателей) позволяет весьма эффективно управлять аппаратурой.

Ага, например, писать в порт для чтения и читать из порта для записи.


Да, конечно — очень часто это игра на грани. Конечно, довольно часто она приводит к очень нехорошим последствиям. Конечно, надо думать как от подобного защититься. Я ж против этого ничего не имею. Беда лишь в том, что любое современное решение это очень плохой компромис. Даже в сравнении со старым и проблемным С.

[citation needed]


Можно пенять на С говоря смотрите — CVE на CVE сидит и CVE погоняет. Но где хоть какие-то гарантии того, что в оставшихся 99% дырок меньше. Просто нашему 1% уделяется самое пристальное внимание.

Ну так-то не 1 процент, а где-то 70.


Только вот обвинить язык С в том, что именно на нем лежит вся вина… Что он провоцирует написание кривого кода…

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



Нет уж. Мне больше по душе демократия С.

А это не демократия, это анархия. Если опыт IT-индустрии что и показывает, так это то, что писать код на C без уязвимостей — за пределами способностей простого смертного.

Ну ведь уже обсуждалось неоднократно. Неопределенное поведение… Ну да. Вопрос в том, что если в определенной точке ОЖИДАЕТСЯ переполнение, то его можно уловить либо расширениями компилятора (как в gcc) либо опусканием на уровень ассемблера и контроля флага переполнения. А если не ожидается, то и пережить его не получится — алгоритмическая ошибка. Про порты — язык С позволяет все, что может процессор. Порт — не часть процессора. Порт часть устройства. Более того, есть практика борьбы с частью названных проблем с помощью const (но лично я ее не поддерживаю). Ах да, простите. Хороший компилятор и алгоритмические ошибки выщучивать должен. Жеваный доширак, который ленивому программисту еще и помочь проглотить надо. Может проще дождемся когда ИИ начнет код писать? С такими компиляторами это не так уж и сложно.

[citation needed]

[ignored] Считаем авторскими мыслями. Раз цитата не приведена.

Про 70%… Ну читайте внимательнее. По сути это говорит о последствиях взрывного роста популярности C++. Авторы той статьи сильно больше спровоцировали приход «кодеров» в свои продукты «выкатив» такие надстройки над WinAPI как MFC. Так ведь еще раз — на свете ничего не дается бесплатно.

Да и список ваш. Тот, который на НЕ начинается. Целиком и полностью выдает ровно то, о чем я говорю с 0xd34df00d Все перечисленные проблемы сильно мешают в плюсах. В обычном С память по нулевому адресу это просто память по нулевому адресу. Ее можно читать, ее можно писать. Никто не может ограничивать конституционную свободу автора читать и писать из любого места (а равно делать что хочешь, не противоречащее закону). А все, что противоречит тут же прибивается с помощью SIGBUS/SIGILL, DATA_ABORT_HANDLER, PREFETCH_ERROR_HANDLER и множества других механизмов специфичных для разных платформ. Меня как раз радует возможность писать что-то типа
switch (fn(a,b,c)) {
  case x:
  case y:
    do_required_prepare();
  case z:
     do_required_job();
     break;
  case_t:
    do_nothing();
    break;
  default:
    err("WTF!\n");
}


И строго по мне, все остальное либо «коммунизм в отдельно взятой песочнице» интерпретируемых языков, либо «олигархический капитализм». Для меня компилятор — партнер и советчик. А не надзиратель в тюрьме. И именно за это любят язык С.

Впрочем, воображение уже рисует цветастую картину. Ночью, под завешенными шторами, на отключенном от интернета компьютере ковыряем залоченный загрузчик myPhone 200 и запускаем на нем код, написанный на находящемся вне закона языке С. Впрочем, завязываю шутить. Есть у моих шуток дурацкое свойство — через некоторое время оказываться пророчествами.
UFO just landed and posted this here
Не… Давайте не передергивать.

вы ж сами пишете, что на раст вам перекатываться лень (синтаксис там непривычный, заголовочные файлы конвертировать надо…)


Я сказал первое впечатление отрицательное. Я же сказал, что не смотря на это пробовал в деле. И таки конфертировал. И поплевался, но по минимуму освоил синтаксис. И даже результирующий ассемблерный код посмотрел. Спасибо вынужденному безделью во время пандемии. Т.е. результат «не лень» это переписал все свои проекты на Rust? Тогда согласен — лень. В остальных случаях не надо приписывать мне того, что я не говорил.

Более того, сноска в 6.5.3.2/4 прямо говорит, что вы неправы:


Хороший вопрос. У меня есть чипы, на которых ROM размещается с нуля. И вектор сброса там. И как его тогда читать непонятно. И не менее непонятно, чем мне могут помочь в этом плане другие языки (ассемблер — вас это не касается). Потому, неверное, плакать. И страдать. Или, что более вероятно, плюну на эту сноску как это сделали разработчики компиляторов. Но в целом вопрос на пятерку.

Стандарт ограничивает. Более того, стандарт запрещает даже вещи типа...


Да. Но еще раз — компилятор друг. Поэтому ругнется Warning'ом (а может даже и Error'ом). Но никак не запретит мне использовать явное приведение типов. «Ну, раз ты уверен — я не возражаю». А я лишний раз проверю не перемудрил ли я с такими конструкциями и нельзя ли сделать проще и понятнее.

Вообще я смотрю на те примеры, которые приводе Вы и диву даюсь. "Доктор, откуда у Вас такие картинки"?

И правильно что стандарт ЯВНО ограничивает применение подобных конструкций, требуя их четкого подтверждения автором. Разве это говорит против С? По мне как раз «за».

А вас не смущает необходимость следовать всяким там MISRA C при написании кода на сях для автомобилей, например?


Знаете, как все связанное с С — больная тема. Я безусловно признаю полезность MISRA. Вот просто безусловно. Больше того, когда судьбинушка заносит в IAR обязательно ставлю эту галку как минимум на «посмотреть на грабли». Но… Уж очень разные чипы. Уж очень по разному устроена кодогенерация у разных компиляторов (даже не смотря на простоту внутреннего мира С). Потому временами рекомендации MISRA сильно ухудшают читаемости (а значит сопровождаемость) и скорость кода. Потому если нет жестких требований, то «поверю, посмотрю на вывод, где сам считаю нужным поправлю». К счастью (или несчастью) у меня пока не было ни одного проекта где MISRA была бы в обязательных требованиях.

Но ведь это та самая демократия. Хочешь ограничивать свободы — плати соразмерную цену. Нет?

Но потом я пришёл на работу, где люди моим кодом будут торговать на бирже, и где есть реальная ответственность, от материальной на много-много денег до уголовной...


Вы вот упомянули автомобильные системы. Да, там MISRA. Но и там жизнь и здоровье. При чем еще неизвестно где больше. Впрочем, мне вот интересно, а BIOS в тех вычислительных системах, на которых крутой и верифицированный код работает на чем написан?

Опять же речь о применимости инструментов. Об ограничении одних сверху, других снизу. Я совсем не хочу «С везде».
UFO just landed and posted this here
А что ты хочешь доказать?
UFO just landed and posted this here
Это редуцированные примеры того, с чем я сталкивался и что приводило к проблемам в продакшене. Могу ещё мноооооого таких примеров привести.


Тяжела жизнь прикладника. Мне бы такое даже в страшном сне не могло присниться. Интересно код в продукт каким путем шел. Не, я понимаю чего хотели добиться в каждом конкретном примере, но хоть убейте не понимаю зачем чесать левое ухо правой рукой, да еще и обязательно пропущенной под левым коленом. Очевидно так смогут не все.

Что до так пугающих множественных UB — так их количество растет вместе с ростом вычислительной техники. Сначала endian-, потом align-, потом многоядерность-многопоточность. Везде, где нельзя гарантировать одинаковый результат на разных платформаю рисуется UB. И это меньшее зло, чем отдавать предпочтение одной платформе и «давить» другую.

Чуть хуже дело обстоит с оптимизацией. Впрочем, я уже говорил в других темах. Основная борьба — это борьба с оптимизатором. Вот тут да… Но, блин — ведь я за это должен быть благодарен как раз прикладникам. Это их стараниями появились странные оптимизации и принудительным inline-ингом или наоборот выносом кода в отдельные функции. Потому привычка писать с "-O none" и в крайнем случае использовать "-O size" давно и неискоренимо выработана. Борьба за размер или скорость — это моя борьба. Я и ее не хочу доверять компилятору.

Ничего вам не поможет, счастливой отладки!


Спасибо. Именно за уничтожение этого кактуса методом сгрызания мне деньги и платят. Больше того — у меня в ряде случаев нет даже отладчика или debug-консоли. И тем не менее, я продолжаю считать С лучшим НИЗКОУРОВНЕВЫМ языком.

Много релевантных ворнингов от компилятора видите?


По разному. Сильно зависит от компилятора. Но тут привычка проверять код на разных компиляторах в параноидальном режиме рулит. Не скажу что они уж очень редки.

а вот кардиостимулятор я бы предпочёл ...


Ваше право. Я, к слову, не знаю про требования к ПО медицинского оборудования (и даже не уверен что они вообще есть). Но сталкивался с требованиями к железкам. Применительно к заданной теме самое тяжелое там обеспечить не «мусор на входе — мусор на выходе», а «мусор на входе — аварийный режим (фиксированная индивидуальная программа)».

На сях… и это не моя головная боль.


Ну так я снова и снова предлагаю вернуться к началу. Может не надо мешать нам грызть кактус. Тем более, что рецептура текилы нам давно известна. Мы рады, что нам сочувствуют. Но менять особо ничего не хотим.
Самое обидное, это то, что ни в одной из прочитанных книг не говорилось прямо: код, собранный с -Os, может проходить тесты, а код -O3 их может проваливать, даже если программа написана с соблюдением стандарта. В такие моменты ценность тестов особенно чувствуется :)
И все же это чисто плюсовая заморочка. Ну не пишут более-менее толковые разработчики на голом С код, который может быть выкинут оптимизатором. Особенно в ядре, драйверах и под контроллеры. А вот плюсы… С их «кодом на все случаи жизни». Сначала научили компилятор выкидывать не нужный в проекте код, максимально обдумывать код уже на этапе компиляции, потом установив высокую оптимизацию дали ему полный карт-бланш — делай что сочтешь нужным. Он и делает ровно то, что попросили. Потом почему-то обижаются — что ж он такое понаделал… А виноват в итоге оказывается вообще язык прародитель. Да нет, ребята. Не надо на зеркало обижаться. И инструменты, которыми работаем знать надо.

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

А вот что с этим делать? А ничего не делать. Жить как живется. И не писать «мертвый» код по возможности.
UFO just landed and posted this here
UFO just landed and posted this here
Я грозился завязывать. И завязываю. Но не спокойно на душе, когда остались «висящие в воздухе» вопросы. Потому не смотря на ясность позиций, все же отвечу. Не столько Вам, сколько окружающим (судя по выставляемым оценкам тему все еще считают интересной).

— И это меньшее зло, чем отдавать предпочтение одной платформе и «давить» другую.
— Конечно. Но проблема не в этом, а в том, что no diagnostic required.


Ну так я нигде и не говорил, что С это золотой червонец, который обязан нравится всем. Вы приводили ссылку на стандарт. Мне страшно представить насколько обесценятся предупреждения компилятора, если на каждый чих оттуда выдавать Warn'инг. Кому это реально важно — есть статические анализаторы. Более того, «no diagnostic required» у «хороших» компиляторов не превращается в «diagnostic no required» (странная русско-английская игра слов, призванная сказать что часть компиляторов диагностику таки выдает).

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


В частности IAR очень любит поругаться на выравнивания. Местами даже не по делу. Нет у меня под рукой единственного проекта где я его Warning не смог побороть, потому привести его не могу. Уж поверьте на слово — ругается. GCC сильно не любит смесь знаково-беззнаковых операндов, способных привести к потере знака в результате. Опять без примеров. Просто потому, что под рукой нет. Но сталкивался. Clang фанатично выверяет форматную строку. Это из самых известных. Вообще, хорошая тема для отдельной статьи. Я, пожалуй, попробую выкроить на нее время. Оно того точно стоить будет.

Но пока у меня выход ядра 5.10(.1) каким-то боком поломал загрузку на I.MX6. Как минимум наблюдаются проблемы с видео и сетью. Видимо удаление платформенного кода не прошло даром. Надо разбираться… Пока не гонят, но когда гнать начнут у меня уже решение должно быть.

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


Нет же. Я уважаю коллег по цеху и далек от мысли о том, что оптимизатор «глючный и бажный». Да и вопрос что в Вашем понимании «хакерский код». Мне кажется, хакерский код — это лаконичный, понятный, самодокументирующийся код. Посмотрите на код ядра Linux. В подавляющем большинстве случаев он предельно прост, понятен и не оставляет особого простора оптимизатору. Потому его выключение мало на что влияет. Можно и включить — только это приведет лишь к увеличению времени компиляции. Больше того — временами я делаю тестовые сборки со всеми возможными уровнями. Ровно затем, чтоб убедиться — не ломается.

[OFFTOPIC] В одной из тем я наловил минусов, пытаясь объяснить за что ж я не люблю ST Microelectronics. Так вот как раз за это. CamelCode, излишняя многословность. А когда начинал знакомство с ними еще и зависимость от уровня оптимизации. С моей колокольни фу-фу-фу. [/OFFTOPIC]

Ну и тут есть ещё такой аспект, что… ну, короче, дети же смотрят!


Да. Только вот у нас очень разный подход к этому факту. Я пытаюсь сказать — учите. Начать очень просто, а дальше сами поймете. А вы отпугиваете излишними сложностями. Впрочем, это даже хорошо. Запретный плод всегда сладок. И манит он как раз самых любопытных и любознательных. Потому альфа и омега, лед и пламень, ангелы и демоны… Но именно в паре. Нельзя чтоб одна сторона перевешивала. Надеюсь у меня получилось.

А вообще странное разделение, я его перестал понимать.


Да. Водораздел здесь не очевидный. И каждый его ставит себе сам (если ставит, конечно). Для меня, все что непосредственно взаимодействует с железом — то системное. Остальное — прикладное со своим делением. Но это, конечно, условность. Потому как разработка компиляторов, обработчики протоколов в ядре, стеки типа mac802.11 — безусловно системное программирование, а непосредственно железа вроде не касается.

Впрочем, я стараюсь не отнимать хлеб у прикладников (по своей классификации). И, боже упаси, учить их правильному подходу к программированию. Соответственно ровно такого же отношения ожидаю к себе.
Ну так я нигде и не говорил, что С это золотой червонец, который обязан нравится всем. Вы приводили ссылку на стандарт. Мне страшно представить насколько обесценятся предупреждения компилятора, если на каждый чих оттуда выдавать Warn'инг. Кому это реально важно — есть статические анализаторы.

На самом деле это важно всем. И нет, ни компиляторы, ни статические анализаторы толком не помогают.

UFO just landed and posted this here
И, между прочим, заметьте как же прав компилятор в каждом из ваших примеров.

int foo(int *ptr)
{
    int val = *ptr;
    return ptr ? 1 : 0;
}


Чистая единица. val — локальна, и нигде за пределами функции не живет, но раз в нее есть запись из указателя, который не проверяется, значит указатель не NULL — а значит ну его к лешему — return 1 и нафиг. А если убрать присвоение (не вошедшее в бинарь, но участвующее в кодогенерации) проверка вернется. Потому как тогда указателю веры нет.

Можно я второй пример разбирать не буду? Там поведение компилятора ровно так же очевидно. Вся фигня с этими примерами — время жизни локальный переменных. Правда отягощенное высосанным из пальца странным доступом к рядом расположенной переменной. Потому со всей ответственностью — притянуто за уши.

Вопрос подачи материала. Эмоционально и с матами у Вас или взвешенно и с пониманием у меня.

Вообще, кинули бы личкой подобного. Хорошие вопросы для собеседования кандидатов и обучения молодежи. На знание и понимание особенностей работы компиляторов в языка С. Я, в силу склада характера, подобного даже придумать не смогу.
UFO just landed and posted this here
А это, кстати, интересная тема…


Да проще все… Вы сильно увлеченный человек. Ваше право. Я, лет до 25 таким же был. Потом дошло — жизнь программированием не начинается и не заканчивается. Есть и другие темы. Важные и интересные. Да и объять необъятное не получится. Закон качалки гласит — всегда найдется человек, который твоим весом только разминается. Потому плюнул и стал сильно спокойнее относится к тому, что на свете много людей куда более умных, нежели моя наглая морда.

Одна беда — в религиозные споры типа этого не влезать так и не обучился.

А статью жду. И, думаю, все же стоит закругляться. Тут, пожалуй, все уже сказано.
Ага, например, писать в порт для чтения и читать из порта для записи.
Емнип, битбэнг на avr как раз так и работает.
UFO just landed and posted this here
Отнюдь, проблема именно в С, а точнее, в несовместимости С с потоковой крупномасштабной коммерческой разработкой. Язык для своей ниши требует слишком высокой дисциплины от всех участников процесса, а дисциплину эту настолько высокую практически невозможно обеспечить, потому что это самое обеспечение требует несовместимых с реальностью затрат времени.

Вот хороший пример кода на С, обмазанного достаточным количеством кода на AstraVer для того, чтобы доказать его корректность. Написание всего этого кода (весь проект — гарантированно безопасный загрузчик PE-образов для UEFI) заняло у двух не самых глупых товарищей полгода, а я такой же загрузчик на том же С (но уже без каких-либо гарантий, кроме «от фаззинга не падает» и «мамой клянусь») написал в 2016 году за три дня. В итоге программировать на С так, чтобы гарантировать отсутсвие ошибок, могут себе позволить только те, кто сидит на финансировании из бюджета, и потому по времени практически не ограничен, а коммерческие компании вынуждены бежать, сломя голову, только чтобы на своем месте оставаться, и потому практически весь их код на С не выдерживает никакой критики с точки зрения безопасности.

В итоге недостатки слишком много позволяющего языка пытаются чинить в железе, уже занесли туда теневой стек (Intel CET), подписывание указателей (ARM PAC), тегирование памяти (ARM MTE), и теперь работают над заносом туда же контрактов, которые будет расставлять компилятор, потому что программиста это делать невозможно заставить (CHERI).

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

Короче, если у вас пока что на С все работает и жрать не просит — смело продолжайте на нем писать. А у нас вот давно уже от С геморрой сплошной, а заменить его толком не на что, потому что C++ — это такое же хтоническое чудовище, вид сбоку, а внедрение Rust пока буксует по экономическим причинам (дорого переучивать всю ораву, дорого писать клей, дорого переписывать то, что не получилось приклеить, а дело делать надо уже сейчас).
Драка


А давайте все же скажем, что проблема здесь не в языке C как таковом. Синтаксис языка С сильно проще и понятнее синтаксиса любого ассемблера. При этом в подавляющем большинстве случаев современные компиляторы весьма эффективно перенесут код на С любую платформу и с радостью воспользуются killer-фичей этой платформы при генерации кода. И даже многопоточная и многопроцессорная обработка не противопоказаны языку С.

Проблема современного С, как то не странно — это его стандартная библиотека. Вот она явно требует пересмотра. Все эти errno при фиксированном возврате -1. Даже в ядре возвращается -ERRNO, что сильно более разумно. Все эти странные флаги и параметры времен расцвета железных терминалов и перфокарт. Впрочем, если заменить ее умрет язык. Убьем священную корову обратной совместимости. Этого не простят. Потому, увы, но… Кактус этот еще грызть и грызть… Боюсь, тут даже Rust не поможет. Впрочем, применительно к UNIX, я готов согласиться — init и выше уже не тема для языка С. А вот ядро и ниже — еще какая тема.

А уж для контроллеров — так вообще безальтернативно. Сегодняшний Rust для них — это тот же С, только с непривычным синтаксисом. Да и опять контроллеры — это минимальное время, а минимальное время никак не вяжется с безопасностью. Триада скорость, понятность, безопасность. Как всегда — максимум два из трех. Впрочем, по мне именно С разумный компромис для всех трех. Опять же — может просто потому что для меня это привычный инструмент.

А про большие проекты, с программированием на скорость. Ну да, тут сложно. С одной стороны не поспоришь. Все так. С другой стороны — а разве можно сравнивать анархию с С и порядок и тестирование на других языках. Чертов «человеческий фактор» всегда самый главный. И уж следом идут средства разработки. Впрочем я повторюсь про «init и выше». Время, когда всю систему необходимо было писать на низкоуровневых языках типа С давно прошло. И, если честно, нет о нем особых сожалений.
Проблема именно в языке как таковом. Язык оказался принципиально не совместим с человеками, потому что человеки делают на нем ошибки (они неизбежны по человеческой природе), а ошибки эти имеют непредсказуемые последствия. Вот такие, например, последствия имеет банальное переполнение буфера даже с учетом всех вообще технологий предотвращения эксплуатации. И это на платформе, в безопасность которой ежегодно вкладываются сотни миллионов долларов, а в результате все равно одна небольшая ошибка (забыли добавить новое значение в switch, отчего сработал слишком разрешительный default) приводит к получению полного контроля над удаленным устройством без участия его владельца.

Хорошо сделанная система, которая взаимодействует с людьми, должна учитывать ограничения этих самых людей, и минимизировать как количество ошибок, как и глубину распространения эффектов от них, а в С вместо этого половина конструкций языка — это undefined behavior, а из другой половины разного рода острые грани торчат, про которые никто толком не знает, пока эти грани в очередной раз не разорвут всю безопасность на немецкий крест. Хороший язык должен по умолчанию следить за тем, чтобы пользователь не творил ерунды, а если ему надо ее творить, чтобы это творение было явным, и чтобы у каждого такого места «пошел в пень, компилятор, я лучше знаю» обязательно стояла табличка «ОСТОРОЖНО, РАБОТАЮТ ЛЮДИ!». А в С эту табличку надо программисту на лбу рисовать перманетным маркером.
Убить всех человеков!

Слушайте, я не могу ничего возражать. Безусловно, во всех современных бедах виноваты люди. Это они изобрели атомное оружие, это они устроили глобальное потепление и озоновую дыры. Может чего тут мелочитьсся — всего-то запрещать писать на С (а паче на ассемблере — там косячат даже самы опытные). Я не верю в возможность написания программ без ошибок вообще. Во всяком случае живыми людьми. Не стоит недооценивать изобретательность отдельных индивидов.
Не надо ничего запрещать, но необходимо улучшать инструменты, чтобы делать меньше ошибок. Никто не говорит ни о запрете (написал же выше, нравится — пользуйтесь на здоровье), ни о полном решении проблемы ошибок. Я тут говорю о том, что нужно бороться с постулатом из известной шутки про то, что «если бы строители строили так, как программисты программы пишут, то первый же залетевший дятел разрушил бы всю цивилизацию». Улучшать инструменты, обучать человеков пользоваться ими, искать замену технологиям, которые доказали свою принципиальную сложность и непознаваемость.
Так с этим-то как раз никто не спорит. И даже я, фанатичный сторонник языка С, согласился бы сменить его на что-то более удобное в работе. Бог с ним контролирующее, но хотя бы рассказывающее во время сборки о потенциальных граблях.

Другое дело, что на сегодня я не вижу достойных альтернатив. Как в самолете — тошнит, а выйти не получится. Впрочем, меня уже не тошнит. Тошнило от необходимости писать на ассемблере. Вот тут да. Пришедший ему на смену C казался раем земным.

Больше того — жизнь меня усиленно учит тому, что я сильно недооцениваю производительность современной вычислительной техники. Но с этим уже ничего не сделать. Я честно пытаюсь себя перебороть, но привычка «ксорить указатели» сидит глубоко в подкорке. Как и привычка считать такты и смотреть результирующий машинный код.

Мне, если честно, страшно не хочется жить в мире в котором ошибки программиста исправляет компилятор. Извечная проблема: кто контролирует контролеров? Мне спокойней считать, что самый низкий уровень кода проходит качественное тестирование, а ошибки… Они случаются.
Мне, если честно, страшно не хочется жить в мире в котором ошибки программиста исправляет компилятор. Извечная проблема: кто контролирует контролеров? Мне спокойней считать, что самый низкий уровень кода проходит качественное тестирование, а ошибки… Они случаются.

Компилятор, который испрааляет код, это как раз таки случай C/C++, где вместо того, чтобы не дать вам скомпилировать UB, компилятор соберет то, что ему будет удобнее, иногда даже не предупредив вас об этом

Логика работы оптимизатора в общем-то понятна: модификация неиспользуемого значения выкидывается, проверка, которая при соблюдении стандарта, всегда даёт 0 или 1, к ним и приводится. Но если для первого случая есть предупреждение unused variable, то флага -Widontrememberthestandartbyheart к моему огромному сожалению не завезли.
UFO just landed and posted this here

Тогда может сразу из спеки бинарь генерить? :)

UFO just landed and posted this here

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

UFO just landed and posted this here
Но он и не для всякой осмысленной спеки годится, раз уж он не полон по Тьюрингу. И тогда исходный комментарий точнее переформулировать как «для некоторых спецификаций вполне возможно писать программы, доказуемо следующие спецификации».
Кроме того, в этом случае генерация бинарника по спеке — вполне алгоритмически разрешимая задача.
UFO just landed and posted this here
потому что C++ — это такое же хтоническое чудовище, вид сбоку
тем не менее не допускать ошибки в плюсах намного легче. Если не писать на «си с классами» конечно же

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


Вот только хочется-то большего. Например, чтобы компилятор следил за инвалидацией итераторов...

Для меня странно, что в разрезе «потоковой разработки» никто не упомянул систему include/library. Она, конечно, позволяет делать всякие хитрые штуки — но даже с «примочками» вроде CMake и autoconf требует значительных усилий для поддержания CI/CD и релиз-конвейеров — что в свою очередь затрудняет автоматические тесты и анализ кода.

Я в общем-то согласен с тезисом про границы применимости и инструменты для системщиков. Жил бы С только как кроссплатформенный ассемблер — не было бы проблем.
Однако для меня как прикладиника основную головную боль представляет именно просачивание С туда, где не совсем хочется его видеть. И начинается всё тут с C interface для большого количества чисто прикладных библиотек. И вообще использования С как lingua franca.


К примеру, заголовочные файлы. Почти всегда с макро-константами. Иногда с "особо альтернативными" макро-константами или вообще кусками кода, засунутыми в макросы. Вроде первичной инициализации структур. Если нужно сделать из этого богатства биндинги для чего-то, не являющегося С или С++, приходится либо искать генератор, умеющий такое парсить, или писать руками. Особенно весело для больших библиотек с заголовочными файлами на несколько тысяч строк.
Связанная проблема — макро-константы для условной компиляции. Опять же, решение или надо тщательно искать (если вообще есть), или писать руками.
Ещё одна связанная проблема — зоопарк целочисленных типов. Fixed-width integers появились только в C99.
Короче говоря, я хотел бы видеть в качестве языка описания бинарных интерфейсов что-то более строго типизированное и без макросов.

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

WASM?

Он вроде немного не про то. Я не уверен, что интерфейс какой-нибудь user32.dll можно будет записать в виде WASM-файла, не создавая лишних прокладок. Если вы про инициативу WASI, она про создание и стандартизацию некоего аналога POSIX, доступного на любой не-браузерной реализации WASM.

Ммм,
«Dynamic languages may not catch problems at compilation time but if they have a strong type system»
Звучит как-то странно, учитывая что динамическая типизация и строгость/слабость системы типов ортогональные характеристики.
Думал, ошибка перевода, но и в оригинале такая же фигня.
Был же более-менее хороший разбор habr.com/ru/post/161205

Имхо, с С классическая проблема «бросить жалко». Так много времени и денег в его экосистему вложено, что ёжики будут плакать, колоться, но продолжать жрать кактус.
Вот как раз экосистема у него кошмарнейшая. Она уже устарела на полвека. Чего стоит одна только проблема с зависимостями. Там, где в любом современном языке зависимости подтягиваются автоматически, причём сразу нужных версий, в случае C каждый городит свой велосипед. Или не городит, и тогда зависимости искать и собирать приходится вручную.
Система сборки — отдельный ужас. Ох как «весело» шерстить на предмет ошибок makefile размером в 250Кб, где к тому же значительная часть кода по 15 раз повторяется. Дублирование кода — это настолько явный антипаттерн, что смело позволяет считать make дерьмом. Именно поэтому поверх него практически во всех мало-мальски крупных проектах набрасывают дополнительные скрипты. В итоге чтобы уверенно собирать чужие проекты на C, вам мало знать синтаксис make-файлов. Вам ещё потребуются знания bash, Perl и Python на уровне, достаточном, чтобы разобраться в проблемах, когда сборка упадёт.
(минус не мой)

Вы как-то узко понимаете термин «экосистема». На и под С написаны, наверное, миллионы библиотек для тысяч устройств, и, наверное, все типы возможных задач — и это всё тоже экосистема.

Я бы, например, был бы рад иметь бесплатный вариант github.com/coin-or/Ipopt на обычно используемом мной .net, да ещё чтобы с хорошим кодом, но это так не работает.

Если я правильно помню слова коллеги, у нас до сих пор используется версия, где .net обёртка над ipopt, внутри которой c, с которым сконнекчены куски фортрана, потому что изначально ipopt наполовину на фортране написан.
Насчет конкретно ipopt не знаю, но большинство библиотек не проблема собрать как so\dll библиотеку и использовать с любым языком который умеет загружать библиотеки. Это не требует писать ни строчки кода на С, поэтому эти библиотеки можно с тем же успехом считать частью экосистемы для остальных языков.

Потому от makefile и уходят, где могут, благо CMake (в разы лучше, хоть и не без своих затей) есть, и учить только его и придётся. Не вижу смысла использовать make в новых проектах совсем.


Ещё есть QMake и Meson, но с теми мне сталкиваться не приходилось особо.

CMake еще хуже. Шаг влево-вправо — баг на баге.

Советую попробовать собрать FLTK для Windows, или попробовать вписать в Cmake свой тулчейн.

На cmake можно собрать и настроить что угодно. Но поддерживать эти тонны скриптов более-менее крупного проекта это боль.

«Dynamic languages may not catch problems at compilation time but if they have a strong type system»
Звучит как-то странно, учитывая что динамическая типизация и строгость/слабость системы типов ортогональные характеристики.
Думал, ошибка перевода, но и в оригинале такая же фигня.
Был же более-менее хороший разбор habr.com/ru/post/161205
Зависит от терминологии. В определениях приведённой статьи — да, в определениях из, например, TAPL(книга), скорее нет, т.к. типы там определяются как статически гарантируемые свойства программы, а динамическая типизация — оксюморон.
Уже 3000 раз говорилось что TIOBE показывает только хайповость языка. Как часто делали запросы с ним. Проплатите какой то говорящей голове на крупном медиа и рейтинг поползет вверх. Так что ни о чем серьезном рассуждать нельзя опираясь на их данные, а уж темболее о замене С.
Косвенно и ± километр из TIOBE можно прикинуть сколько людей пытается изучать тот или иной язык(программистами они вообще никогда могут не стать, но на статистику повляют) и насколько язык удобен в использовании.
Гуглил недавно как в Java добить строку нулями слева до фикс длинны. Я искал что то вроде String.leftPad, но не нашел сам. Через гугл я конечно выяснил что это делается через String.format. Но я увидел и большое количество людей которые делают это руками сами в разных вариациях, вплоть до цикла со сложением строк через "+". Очевидно что вот в этом месте проблема. И я поднял рейтинг языку, просто на пустом месте. Вы скажете — «Ты субьективен! Проблема только у тебя и вообще ты никто.». А вот нифига, во всех библиотеках она примерно так и называется как я и ожидал. Значит люди ждут именно это, а не String.format который пришлось гуглить.
И я поднял рейтинг языку, просто на пустом месте.

Нет, не подняли. Тиобе так не работает. А работает вот так.

Теоретически, если он запрос вбивал как
Java programming how pad string with zeros
то повлиял))
Конечно маловероятно, потому что запрос смотрится по дурацки

Не запрос.


Tiobe ищет страницы на которых есть текст "java programming". Вот, если бы на форуме спросил, то да, поднял бы рейтинг джавы.

У языка C есть два самых больных места:
— Разыменование невалидных указателей
— Отвратительная реализация строк с возможностью выхода за их границы

Читая новости об очередных найденных «уязвимостях» в системных библиотеках, создаётся впечатление что из них 99% вызвано исключительно этими недостатками языка. И пора уже признать что ввиду системности этого явления это не вина «плохих» программистов, это именно ущербность самого языка.

Любой язык, который сможет решить две этих проблемы без потери преимуществ C потенциально является его «убийцей».
Именно так.

Работа со строками, а равно форматная строка printf/scanf — это любимая мозоль любого, активно пишущего на языке C.

Языки типа С++ пытаются побороть строки и абстракции драйверного слоя (что сильно важнее). У Apple даже получилось переписать BSD'шное ядро на плюсах. Microsoft уже довольно давно использует плюсовый код в ядерной части своей ОС. Может быть в этом и есть что-то. Но массового перехода нет. Или «мир еще не дозрел», или… Преимущества ощутимы при «корпоративной» разработке, но плохо работаю с открытыми проектами? Не знаю. Для меня пока факт — используется, но не очень активно.

И да, сам язык не имеет ничего против разыменовывания ЛЮБЫХ указателей. Вообще. Он абсолютно бесприкословно выполнит то, то его попросят.

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

Языки типа Rust борются с ними выстраивая эшелонированную оборону над ресурсами. Т.е. пытаются сделать то, на что разработчики чипов пожалели транзисторов и тактов. Их право. В определенных случаяю, возможно, и стоит сильно пожертвовать скоростью ради безопасности. Но победа Rust над C на низком уровне как раз и будет грозить резким падением производительности на прикладном. Стоит ли оно того? Ну время покажет. Rust активно растет. Правда пока все больше на прикладном уровне, пытаясь конкурировать не столько с С, сколько с С++. Потому ждем.

Так что «недостатки языка» — это кому как. Если скальпель для хирурга очень острый, то возможно не стоит начинать оперировать. Возможно для всех будет лучше, если такой хирург возьмет не такой острый топор и пойдет дрова рубить. А «уязвимости»… Ну, кто сам без греха пусть первым бросит камень. В конце-концов в мире WEB-программирования (где языка С нет чуть больше чем совсем) они весьма и весьма не редки.
UFO just landed and posted this here
Патомушто!

Дык это — такты конечны. Аппаратных блоков контроля указателей и работы со строками нет. Значит контроль программный. Значит такты. При каждом (ужас) обращении к строке или указателю (массиву). Перед одной-двумя ассемблерными инструкциями для изменения байта в массиве, десяток-другой инструкций допустимости подобной операции. А что есть аргументированные возражения? Я бы послушал…
Дык это, в релизных конфигурациях этих проверок нет, только в отладочных. А нет их в релизных потому, что в Rust и других подобных языках с развитой системой типов компилятор может доказать отсутствие переполнений и выкинуть проверки на них, при условии, что сам язык не нарушает свои собственные инварианты (т.н. soundness) и что эти инварианты не нарушены программистом в unsafe-блоках. В том то и фишка, что никто не предлагает проверять все подряд все время, предлагают писать код так, чтобы проверял компилятор во время сборки.
А можно в общих чертах описать, как на ассемблере будет выглядеть безопасный релизный вариант чего-то типа (внимание, код на несуществующем языке!)

array sample[200] of int;
int i;

fn do_some_with_array()
{
i = get_number_from_user();
a[i] = i;
}

Чтоб так, как описываете вы. Я могу понять, если будут требоваться уточняющие параметры для описания i (индекса). Но где гарантия что их не забудут или они будут правильные? А если массив не статический, а выделяемый из HEAP в процессе работы? Как это можно учесть в момент компиляции?

Если найдется ссылочка «на почитать» буду благодарен. Потому как для меня это пока непонятно.
Проверка одна все равно будет, там, где тип i будет ограничен диапазоном 0..200, т.е. на языке с достаточно строкой типизацией в этой программе выше будет ошибка на строке a[i] = i, потому что слева на i наложены более строгие ограничения, чем справа. В результате компилятор скажет вам «гражданин, наложите дополнительные ограничения на i (предлагаю 0..200), или я вам ничего не соберу, спасибо». А потом добавит эту проверку (один раз при получении значения снаружи), и забыть ее не получится.
Да… А одна из функций кода на С это прототипирование устройства… Оно, наверное, неплохо — получать код, который сразу после прототипирования в product ставит можно, только ведь прототип обычно не один.

Да и вариант с массивом очень прост и по сути (ожидаемо) уперся в валидацию ввода пользователя. А посложнее? А если не ввод? А если вычисление или получение из регистра? Мне ниже ссылку дали. Пожалуй остальное после прочтения. Ладно, будем ждать. Вдруг действительно у «ржавых» все получится. Мешать им я точно не намерен.
UFO just landed and posted this here
Почитайте «Type-Driven Development with Idris»


Спасибо. Почитаю.

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

Провалидировать пользовательский ввод — это вполне себе стандартная рекомендация для любого языка. И на том же C она ровно так же прекрасно сработает. Другое дело, что С не будет требовать. И даже просить. Но это и один из самых простых примеров. Правда, чего уж там, один из самых распространенных вариантов накосячить.

UFO just landed and posted this here

Видите ли, в ситуации когда мы делаем get_number_from_user, мы обязаны добавить проверку. Хоть вручную, хоть автоматически… Потому что данным от пользователя доверять нельзя, никогда. И такты на проверку придётся потратить, от языка это не зависит.


Однако, немного изменим условие задачи:


i = get_number_from_user();
a[i] = i;
a[i+1] = i+1;

Здесь нормальный компилятор уже не будет проверять что i+1>0, так что будет сделано всего 3 сравнения, а не 4 как можно было бы подумать.


Теперь добавим ручную проверку:


i = get_number_from_user();
if (i<0 || i>=199) throw wtf;
a[i] = i;
a[i+1] = i+1;

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

UFO just landed and posted this here

Это уже особенность переполнений :-(

Ммм… Да… Только, простите я потерял нить рассуждения в этой ветке. Настолько, что даже не очень понимаю на чьей Вы стороне.

Первый пример однозначно не безопасен. Для того, чтобы оставить его в «production» коде нужны серьезные причины. Например строго известный размер массива a и строго известные ограничения возвращаемого get_number_from_user() значения. По сути именно это и даст Rust (и иже с ним). Больше того, при попытке что-то поменять внутри get_number_from_user() или размер a поднимется паника — ломаем соседний код. Второй вариант — извечная классика С. Я, конечно, из ссображений педантичности все же сделал бы так
do {
  i = get_number_from_user();
} while ((i<0) || (i>=199));
a[i] = [i];
a[i+1] = i+1;

Но это косметические детали.

Кажется, вы описываете завтипы, которых нет в Rust. А Rust умеет выкидывать проверки при обращении к элементами массива?

Лишку хватанул, признаю. Rust умеет выкидывать часть проверок в релизе (например, проверки на переполнение целочисленных типов, и то можно попросить оставить), но не проверки на выход за границы массивов.
UFO just landed and posted this here

Проверки времени жизни существуют только на этапе компиляции. А если вам нужно убрать проверку на выход за границы массива, всегда есть get_unchecked.


Returns a reference to an element or subslice, without doing bounds checking.

Это то самое "я лучше знаю, что делаю", только выраженное явно.

Контроль форматов printf давно пофиксили.

Дальше простынь не читал
Это как раз фигня для низкоуровневого языка. Основные недостатки ИМХО — древний препроцессор и система инклудов вместо синтаксических макросов и модулей, немного слабоватая система типов (в С++ лучше и близко к оптимальной, в Rust уже ИМХО перебор со строгостью), некоторые нелогичности вроде «имя массива это адрес первого элемента массива», что мешает массивам быть «first-class objects». Еще явный ляп — приоритет битовых операций ниже чем у операций сравнения.
Очередная статья о том, как плох Си и как бы его заменить? Никогда такого не было и вот опять, как говорится…
Хорошая статья — показывает что направление развития языков программирования встало в спираль самоедства.
Применение в качестве средства программирования языка высокого уровня — упирается в ограничения платформы или структуры и постоянно для конкретных задач требует расширения
Применение низкоуровневых языков на базовых логических конструкциях (а С конечно один из таких) — приводит, при наличии гибкости, к сотням сложных обработок и однотипных повторений. Выведение их во фреймворки БЕЗ централизованной модерации — ничего не решает.

Я думаю что С умрет только тогда, когда появится такой инструмент программирования — который позволит погружаться разработчику до машинных кодов, предоставляя в основе своей язык 4-го или даже 5-го уровня для описания алгоритмов. И конечно он должен иметь развитые семантики и инструменты работы с данными и их метамоделями.
предположу, что Вы имели ввиду язык, который в основе своей был бы ассемблером, но позволял бы накрутить на себя любые абстракции, необходимые в решении данной задачи… но у такого языка неизбежно будут проблемы с переносимостью.
Достаточно уровня языка Си. Полноценный Ассемблер нужен крайне редко — возможно тогда, когда используются специальные системные команды для уровня ядра.
А по поводу накручивания абстракций, я еще 5 лет назад писал статью.
Например, в случае сборщика мусора: если он есть и прибит гвоздями к языку (как в Go или D) — язык уже не может быть «системным». Если его нет вообще — это неудобно для высокоуровневого программирования (как в С++). А вот если он есть, но в виде «расширения», которое можно включить или отключить в свойствах проекта — это совсем другое дело.

ИМХО сборщик мусора — слишком инвазивная вещь.


Если вы не хотите видеть GC в системе типов, вы будете всё равно включать его глобально. Причём такой "глобальный включатель" будет срабатывать при наличии хотя бы одного модуля, требующего GC. С принудительными сканами всего и вся и всё равно проблемами, когда кто-то будет случайно руками удалять управляемый объект.


Если же вы хотите выделить сборку мусора в отдельный тип smart pointer'a, у вас будут проблемы с просачиванием его везде, включая сигнатуры методов, поля структур и т.п. Плюс — корни GC будут у вас отдельным типом. Который надо будет аккуратно раскладывать на стек.


Пока что приемлемый сценарий, который я вижу — локальное отключение GC для некоторых значений или типов.

UFO just landed and posted this here
Зачем нужен один универсальный язык для всего? Те, кто пишут бизнес-логику, никогда не опускаются до манипулирования битами и регистрами. А системщикам не нужны сборщики мусора и лямбда-функции. Каждый инструмент хорош в своей области применения.
А системщикам не нужны сборщики мусора и лямбда-функции.

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

K&R делали кроссплатформенный ассемблер, чтобы таскать UNIX между архитектурами, и таки сделали и потащили. Но использовать ванильный С в прикладных программах очень так себе идея, сишные достоинства тут становятся его же недостатками.
С в лоб и без проблем меняется на BetterC

Fin

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

Вы читали Jens Gustedt, который ModernC? У него в блоге движуха по стандартизации описывается. Ну и я не особо понимаю, зачем нишевому языку пытаться активно «пытаться отвечать на вызовы времени»; подход к написанию программ на С незначительно поменялся с K&R, а вот «как правильно писать на С++» меняется чуть ли не каждый стандарт с кучей deprecated. Сям очень не помешает модульность, например, или иные способы ускорить компиляцию и интегрироваться с современными инструментами, но тащить в язык новую парадигму просто бессмысленно, может ненароком какой-то из первых стандартов плюсов или D получиться :)
Embedded чуть ли не весь на С99 пишут.
Лучший язык. Созданный инженерами для инженеров во времена Аполлонов и торжества технического прогресса.
Нынешнее программирование с современными языками — полнейший мрак. Программы потребляют гигабайты, а функциональность и качество только снижаются. Гигабайты!
C печально известен возникновением таких проблем, как переполнения буфера. C — это язык, позволяющий выстрелить себе в ногу слишком большим количеством способов.

Для критических применений есть своды правил, например MISRA. Никто не мешает следовать им и продолжать разрабатывать действительно критически ответственные приложения на «опасном» C. Или кто-то уже разрабатывает или рискует разрабатывать что-то подобное на Java? Я вот побоялся бы сесть в автомобиль у которого АБС написан на Java или Python, например, в котором «так тяжело выстрелить себе в ногу».
почти везде где нужно заменить си на что-то более безопасное, используются языки с GC. Везде где можно заменить си на что-то такое же быстрое, используются плюсы и кое-где пытаются использовать rust. А там где си заменять нечем, он, внезапно, доминирует
swift и nim не подпадают под эту упрощенную классификацию

и это только навскидку

Мы недавно сравнивали Rust с C/C++ в контексте производительности (обусждения на Hacker News https://news.ycombinator.com/item?id=24960108 и Reddit https://www.reddit.com/r/programming/comments/jjtobp/fast_programming_languages_c_c_rust_and_assembly/).


Rust позволяет писать более безопасный код, хотя C++ движется тоже в эту сторону. Интересный доклад на эту тему с CppCon'20 Closing the Gap between Rust and C++ Using Principles of Static Analysis.


Но Rust по своему дизайну делает разработку быстрого кода сложнее (примеры приводил в блоге).


Go для утилит типа ls — вполне, но для ядра ОС, например, очевидно — нет.

Драйвера прикажете тоже на Go писать? Или на питоне?
Может, действительно, стоит оставить язык Си в покое? Раз он дожил до стольких лет и все еще популярен, видимо есть там что-то, что не убить никакими «инновациями».

Касаемо прикладного софта — соглашусь.
Раз он дожил до стольких лет и все еще популярен, видимо есть там что-то, что не убить никакими «инновациями».

Есть, легаси. А ещё дикая косность инженеров, занимающихся программированием для встраиваемых систем.

Вместо минусов предложите язык для ядра, гипервизоров. Нет таких. Есть попытки внедрять С++, но там многие вещи приходится отключать. Rust разве что… Но как там обстоит дело с исключениями и прочими вещами «безопасного кодинга» если перейти в ядро? не вернемся ли к тому, от чего ушли?
p.s. не кодил на rust.
UFO just landed and posted this here
Вместо минусов предложите язык для ядра, гипервизоров. Нет таких. Есть попытки внедрять С++, но там многие вещи приходится отключать.
И в чем проблема? В критичных местах не используем продвинутые фичи.
Rust разве что……
p.s. не кодил на rust.
Чтобы понять недостатки Rust, надо пописать на Rust.
ИМХО, для базы/ядер почему бы и нет
Есть попытки внедрять С++, но там многие вещи приходится отключать
исключения — всего лишь один из инструментов с++, пользоваться ими никто не заставляет. У вас позиция такая, словно лишний для конкретного случая инструментарий делает язык менее применимым, по факту это не так. Моё личное мнение — с++ можно выбрать вместо си примерно всегда, т.к. даже базовое подмножество с++ функциональнее инструментария чистого си.
именно так, но с ремаркой.

нужен опытный в С++ мастер, который скажет, что подаванам можно пользовать иль нет
исключения — всего лишь один из инструментов с++, пользоваться ими никто не заставляет

За исключением того, что хороший кусок стандартной библиотеки завязан на использование исключений для оповещения об ошибках. ЕМНИП стандарт вообще не предусматривает работу с отключенными исключениями.
Как пример, мы теперь имеем двойные интерфейсы в std::filesystem, причём некоторые методы, возвращающие статус через std::error_code (std::filesystem::directory_iterator::increment), всё равно кидаются исключениями.


А ещё кроме исключений у нас есть std::error_code, пропозалы на std::outcome, std::expected и deterministic exceptions Саттера, и дичайший зоопарк методов регистрации, эскалации и обработки ошибок в разных фреймворках (Qt, ау!).


Короче, с С++ будет проблема — на каком именно диалекте вы хотите писать? И не дай бог ваш диалект не совпадёт с диалектом закрытой либы за много чемоданов денег, которую вам кров из носу надо использовать...

За исключением того, что хороший кусок стандартной библиотеки завязан на использование исключений для оповещения об ошибках
в либах, которые не депрекейтят (типа iostream), стараются дублировать API для возврата ошибок через error_code. Разве что ошибки аллокации только через исключения обрабатывать, но там шибко много приколов. В тот же rust ради обработки ошибок аллокаций затащили механизм, повторяющий по принципу работы исключения. И sigkill никто не отменял…
А ещё кроме исключений у нас есть std::error_code, пропозалы на std::outcome, std::expected и deterministic exceptions Саттера, и дичайший зоопарк методов регистрации, эскалации и обработки ошибок в разных фреймворках (Qt, ау!).
проблема в том, что исключения — самый универсальный способ обработки ошибок, но его не любят из соображений производительности (хотя иногда они и быстрее выйдут). С сигналами/слотами Qt'а например тяжело писать последовательный код, std::error_code — хорошая штука, ровно до тех пор, пока не надо кинуть ошибку с неконстантным текстом; в других случаях текст+код ошибки приходится возвращать способами, больше похожими на костыли. Кстати забавно, можно было бы сделать error_code так, чтобы он держал полноценную строку, которая с парой твиков отлично бы работала с константными текстами ошибок.
Короче, с С++ будет проблема — на каком именно диалекте вы хотите писать? И не дай бог ваш диалект не совпадёт с диалектом закрытой либы за много чемоданов денег, которую вам кров из носу надо использовать...
как раз эта проблема решаема, т.к. с++ поддерживает много видов обработок ошибок. Вот если бы с++ например не умел в исключения, а вам бы приходилось оборачивать либу какого-нибудь языка которая ими кидается, было бы больнее.
UFO just landed and posted this here
Если вы про панику, то механизм её перехвата существует только для того, чтобы не пропускать панику в FFI слой.
ну паника под капотом сделана через тот же механизм, что и с++ исключения
Т.е., и производительности от Раста можно не ждать и в перспективе. ОК.

Для несведущих — коду с исключениями недоступные сильные оптимизации. Обсуждается в профильных науч.группах
Для несведущих — коду с исключениями недоступные сильные оптимизации. Обсуждается в профильных науч.группах

А поделитесь ссылочкой. Там какая-то фундаментальная проблема с раскруткой стека, отдельным хранилищем для данных или необходимостью RTTI для перехвата?


Страуструп на предложение Саттера по deterministic exceptions ответил в том духе, что не надо городить огород и лучше просто оптимизировать те исключения, что уже есть. Или это ответ в стиле git gud?

Там какая-то фундаментальная проблема с раскруткой стека, отдельным хранилищем для данных или необходимостью RTTI для перехвата?
функции, в которых несколько landing pad'ов, сложнее инлайнить и делать перестановки. Также растет объем кода этих функций, что еще дальше усложняет инлайнинг. Просто у Siegmarl слишком сильная формулировка, я бы перефразировал как «некоторые оптимизации недоступны»

Интересно, спасибо. Про множество landing pad'ов не нашёл пока. Интересно, нельзя ли генерировать всегда один, с набором флагов внутри что чистить.

UFO just landed and posted this here
Полистал — наверное это все восходит к Саттеру, хотя обсуждается много где в разных языках.

Его блог с разъяснениями и сам документ

Оптимизировать ф-цию с несколькими точками входа-выхода, которую вызывает еще ф-ции с несколькими точками вх-вых итп… в общем случае нельзя, в отличие от 1 вход-1-выход.

И так далее и мы упремся в слабую PGO и проблемы с простотой ABI.

UFO just landed and posted this here
А конечные приложения почти всегда собраны с настройкой panic = abort

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

UFO just landed and posted this here
С сигналами/слотами Qt'а например тяжело писать последовательный код

Вопрос не в последовательном коде. Вопрос в том, чтобы корректно выловить ошибку, произошедшую в некоем асинхронном вызове, показать её пользователю и продолжить работу дальше. В случае с Qt из слота даже нельзя ничего вернуть. В одном из моих предыдущих проектов исключения вкупе с перегрузкой QCoreApplication::notify позволяли прописать обработку всех необработанных обломов в одном месте. Сейчас сижу на QML, который ни разу не exception-neutral.


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

Как раз в этом и состоит проблема. Каждый городит что-то своё. Я не настаиваю на исключениях. Пусть будет какой-нибудь вариант Result'а. Но блин везде. Унифицированно. А не так, что "здесь играем, здесь не играем, здесь рыбу заворачивали".


Касательно другого языка — с высокой вероятностью вам придётся писать клей, даже если и там, и там исключения. Потому что если даже и там, и там они нативные, никто не даёт гарантию, что они совместимые. Даже если и там, и там под капотом SEH.

UFO just landed and posted this here
Потому что паттерн observer не для этого.

Все мои кутешно-плюсатые юкзейсы с асинхронщиной покрывались QFuture + QFutureInterface + собственными темплейтными обмазками, дающими эту (и самодельному подобию Either) типа-монадические интерфейсы.

Не совсем точно выразился. Имеется ввиду любой вызов слота, происходящий асинхронно. А QML предпочитает именно асинхронные вызовы. QFuture это конечно прекрасно, но Qt/QML не рассчитан на его применение повсеместно. Что приведёт к boilerplate везде. Корректное заворачивание нативной логики, чтобы она не обрушила QML engine, тоже требует никак не проверяемого компилятором бойлерплэйта везде. А всего-то надо было добавить хук, позволяющий обернуть место вызова из скриптового движка в нативный код. плюс нормальный сигнал QQmlEngine::exception, вызываемый если скриптовое исключение не было обработано. А не кошмарик QQmlEngine::warnings, перехватывающий вообще всё подряд.

Есть области из которых Си никогда не уйдёт. Например

… Пример того, как язык делать не надо

В отличие от хипстерских недоязычков, С жил, жив и будет жить еще много!
Лично я пишу на С абсолютно все: от микроконтроллеров до бэкенда веб-морд и всяких сервисов. Очень простой язык — тем он и хорош. Нет нужды читать талмуды мануалов, как в случае, скажем, с С++: достаточно осилить книжку K&R.
Ну, когда всякое «небыдло» начинает наезжать на С, я закипаю!
Лучше С языков не было, нет и не будет никогда!!!
А всякие ваши хипстерские педеrust'ы и прочие goвна ни для чего серьезного не годятся! И уйдут буквально через несколько лет…
Тот же пытхон уже давным-давно забыли бы, если б не толпы вантузоидов, которым не завезли баша вменяемого!

Забавно, что код должен хорошо читаться, но с названием этого языка в наших краях не повезло, и сложно читать тексты про Си, когда вместо "Си" — "С".

По мне Си плох тем, что слишком высокоуровневый.
Не хватает ЯП занимающий промежуточное место между С/С++ и ассемблером. Такой ЯП может быть высокоуровневым ассемблером, вроде UASM, только более высокоуровневый.
Кому не хватает? Очереди не заметно.

Просто между изобретением С, и текущим моментом, появилось много разного железа, не ложащегося прямо на С. Но это судьба любого языка.

Даже статья была про это
Давно есть Fort, внебрачный сын ассемблера с лиспом :)
Да, я знаю про форт. Но это сосем не то. Надо что-то более похожее на Си, без всяких стеков. Я бы попробовал добавить в UASM некоторые фичи, вроде лучшей поддержки указателей и ещё (:=, +=… операторы выражения).

Или как когда-то давно язык АЛМО.

Лично я за то, чтобы С умер и большинство пересели на Rust`ы, Javа, С#, Python`ы и прочее.
А я продолжу писать на С, без преувеличения высокопроизводительный код, по сравнению с выше перечисленными инструментами.
И вообще не понятно, автор подобных статей, их что заставляют на Си писать, чем то угрожая?
А я продолжу писать на С, без преувеличения высокопроизводительный код, по сравнению с выше перечисленными инструментами.

А вы действительно сравнивали или это голословное утверждение?

Конечно, к примеру на примере простой задачи — подсчет подстрок в строке. В зависимости от условий: кол-во подстрок, размер подстроки — на Python`е по сравнению с Си, скорость поиска и подсчета медленнее в среднем от 6 до 12 раз.
Как я писал я совершенно не против Python`а, но использовать для парсинга к примеру HTML и XML — я его не буду. Но я только «За», если это будут делать другие.
Поэтому я ни не понимаю претензию в данном случае к Си. Вас кто то заставляет его использовать?
Это всего лишь инструменты, каждый Сам выбирает, что ему использовать.
UFO just landed and posted this here

Немного не понял, а зачем Вы, попробуете что нибудь сделать не на С?
Вы что с чем сравнить хотите ?

UFO just landed and posted this here

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

UFO just landed and posted this here
У меня алгоритм прямолинейный «в лоб».
Будет как раз интересно сравнить тупой алгоритм на С, с хитро-закрученным, так что все честно.
Не люблю высылать исходники, не знай почему :(

Строка:?
Подстрока:?
Кол-во итераций цикла:?
UFO just landed and posted this here
Строка:«Hell&HelloHelloHHell&lloHelloHelloHelloHelHell&loHelloHelloHelloHelloHelloHeHell&lloHellHell&oHello1»;
Кол-во циклов: 9999999

Подстрока_1:Hello
Подстрока_2:&lloH
Подстрока_3:Hello1
Подстрока_4:HelloHello
UFO just landed and posted this here
Спасибо за ответ.
У меня core i5 9600.
Компилировал на VS2017, x64, O2:

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

image

Из скрина видно, что наименьшее время — это 727 мсек, наибольшее 2006.

Или у нас с Вами слишком разные процессоры или че то не понятно. 4.5 секунды много получается.
Вот потому вы и должны были сразу передать «исходники + параметры сборки» и не заниматься ерундой
Спасибо. Да, я вроде бы и не занимался ерундой, насчет исходников сразу написал.
UFO just landed and posted this here
Спасибо!
Скомпилировал Ваш код на VS2017, x64, O2:
-Проверял поочередно по одной подстроке в цикле:

Такое получилось:

Подстрока--------------Ваш код, мс: ------------Мой код, мс
-----------------------------------------------------(лучш/худ)
Hello-----------------------1483---------------------727/2006
&lloH-----------------------1217--------------------179/1526
Hello1----------------------1524--------------------357/1769
HelloHello------------------1581--------------------279/2402
UFO just landed and posted this here
А в хаскеле, есть какие нибудь стандартно-библиотечные функции заточенные конкретно под это дело?
UFO just landed and posted this here
Rust потенциально более производителен, ибо компилятору больше известно о программе, чем компилятору С, соответственно он может агрессивнее оптимизировать. И оптимизировал бы, да вот только LLVM не очень приспособлен к таким оптимизациям, ибо С/С++ компиляторы этой функциональностью не особо пользуются, поэтому она несколько забагована.
Остыньте. Вы ничего здесь не докажите. Против веры воевать бесполезно.

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

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

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

Этот эффект имеет даже какое-то название.
Да, пусть лучше посредственности идут за вами </сарказм?>
Да нет.

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

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

Из этого следует с наибольшей правдоподобностью только одно предположение: а может быть, просто не стрелять? Ну да, язык и качественный код на нем требует качества кодера. Да, это не совсем согласуется с общераспространенными современными практиками «х***к и в продакшен». Но испытанная временем бест практис такова, что если бордель теряет прибыль, надо не кровати переставлять, а эмплойерш менять.
UFO just landed and posted this here
UFO just landed and posted this here
Почему-то в статье забыли про D! Да как Вы могли!

Согласен, D надо упомянуть. Сделать язык со сборщиком мусора и при этом одновременно без memory safety — это надо уметь.

Стоп. А разве в D сборщик мусора не контролируемый? Он вроде вылезает только, когда попросят, я неправ?

А в статье написали, что D так же сложен, как C++. Удивительно, но D зашёл мне гораздо легче. И собственно C и C++ именно он и помог мне понять.
Нет, GC не контролируемый, хотя временно отключаемый, впрочем это костыль.

Но AnthonyMikh тоже неправ. На D можно писать без сборщика мусора, или с '@ nogc' кусками, и с мемори сэфети там все хорошо (единственное исключение — Сишные юнионы).

Еще добавили Растовский (точнее из линейного программирования) механизм заимствования указателей, но никто пока не умеет им пользоваться…

Заменой С является D --BetterC. Исключается 90% Сишных родимых багов, ценой правки 2% кода. Чтобы 2 раза не повторяться — в BetterC нет GC и классов, хотя есть шаблоны и куча всего, так что все же получается >>> C
Нет, GC не контролируемый, хотя временно отключаемый, впрочем это костыль.

Может речь о том что он вызывается только в моменты выделения памяти?
Sign up to leave a comment.