Pull to refresh

Comments 30

UFO just landed and posted this here
Более того, С и не создавался для обеспечения безопасности типов и прочих видов «безопасностей». Этот язык создавался для системного программирования, т.е. для таких задач где программист знает что он делает. Фактически, С — это навороченный ассемблер, в котором возможно практически все что возможно в ассемблере.

Язык-современник С в котором обеспечена «безопасность» — это Паскаль. Он практически не пригоден для системного программирования — слишком много ограничений по типам и run-time наворотов.

Но с тех пор дедушка Вирт успел настрогать Модулу и Модулу-2 и целый выводок оберонов и, внимание, все они нацелены на относительно безопасное системное программирование (Оберон 1 — для написания одноимённой графической ОС, Оберон 07 — для программирования дронов) и даже дружат со сборкой мусора.
Переход на «ручник» решался хаком в лице модуля SYSTEM — его функции почти прямые аналоги ассемблерных команд + компилятор в этом случае позволяет делать ассемблерные вставки. Тут уж никакой сборки мусора, типобезопасности, за всё в рамках такого модуля отвечаешь сам, так же как и в Си.

Фактически, С — это навороченный ассемблер, в котором возможно практически все что возможно в ассемблере.

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

Удивлять должно то, что способность отстреливать ноги и руки — часть стандарта. Это в корне противоречит гуманистическим ценностям (как минимум, в интерпретациях, уравнивающих физическое и психологическое насилие), и простым переименованием веток в репозитории это не исправить.
UFO just landed and posted this here
Аргумент против предложения звучал так: «написано так много кода, который сломается, если мы изменим эти сигнатуры».

С каждой новой версией GCC — отваливается по 10% успешно_работающего кода. Отчего стало модным указывать версию GCC прямо в исходниках.
А способность отстреливать конечности — целиком и полностью заслуга IDE, где проверка Си кода осталась на пещерном уровне.
Тут сломается 99% нетривиального кода и модулей, работающий с другими языками.
> Будь это так, каждый автор компилятора вводил бы что-то вроде Эпох в Rust, Только Для Предупреждений, чтобы дать людям «стабильный» эталонный набор для тестирования.

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

And we have move semantics, perfect forwarding, template argument packs and fold expression on them, SFINAE and 'if constepr' and many many things that would just blow newcomer's mind away.


Honestly I think C++ is becoming "COBOL of our days" — three is a lot of legacy code but many newly graduated developers / programmers are afraid to even touch C++, and C++ committee pushing more and more and more new stuff into the language is making it harder and harder to learn C++ fully for a newcomer.

Жрал я тут недавно плюсовую куку под названием CMake.
Из свежего, с чем уже 3 дня маюсь. Задача простая — собрать с BOOST'ом проект на кластере. Что я нашел недавно обнаружил в попытках понять, почему сборка ломается:

So my current understanding is:

For Boost ≤ 1.69, we can specify the location with BOOST_ROOT as a command line parameter, set(), or environment variable.
The world is :)
But from ≥ Boost 1.70, it will start preferring to use «config mode», meaning it will silently ignore the BOOST_ROOT if we specify it via the command line or set().
But it will continue heeding it if we specify it via an environment variable.
But the new config mode will find Boost directories in new places (eg /opt) and these will silently override our BOOST_ROOT, even if specified via an environment variable (that it otherwise heeds).
To revert to the previous, non «config mode» behaviour, we must specify Boost_NO_BOOST_CMAKE=ON
But this must be specified via a command line parameter or set(); if we specify it via an environment variable, it will be silently ignored.
To specify the location under «config mode», we can specify Boost_DIR
But this must be specified as an environment variable or set( Boost_DIR CACHE ); if it is specified via the command line or the a plain set( Boost_DIR <value ), it will be silently ignored.
There is further complexity with Boost_ROOT (the same as BOOST_ROOT?) and the version of cmake we're using and the version of cmake we've required.
The world is :(

Здесь детальнее о проблеме.

А проблема в том, что экосистема плюсов тяжела, имеет большой порог входа, при этом крайне хрупка. Ясен красен, что одни уходят в Rust, другие на Python. Эмбеддерам в этом смысле не так уж и плохо, когда проект делается под конкретную платформу. Но мультиплатформа на плюсах — это боль и унижение. CMake — худший язык, который я когда-либо видел, ломающий свои же совместимости между минорными версиями.

А как вам цепочка .am -> .in -> makefile?
unix.stackexchange.com/a/84384

Самое обидное, что с новым стандартом порог входа лишь повышается, поскольку надо знать и старые плюсы, и новые. А логика новых стандартов новичкам может быть не очень понятна.
Плюсам не помешало бы сделать что-то вроде С++2.0. Да, будет так же больно как с Питоном2 -> Питоном3. Но без этого язык действительно станет COBOL'ом с сопутствующими болячками и для индустрии, и для специалистов, владеющих им.
UFO just landed and posted this here

В некотором смысле да: виноват в том, что не хочет умирать.


Даже при наличии Rust, уже есть C++ со своими тараканами, CMake со своими тараканами — и они никуда не денутся, насколько бы хорошим ни был Cargo. Поэтому тем, кому приходится работать с C++, остаётся лишь облизываться и продолжать страдать. Потому что библиотека, которая им нужна, к сожалению, на C++, а альтернатива ей сама из воздуха не появляется.

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

static I: i32 = 0;
static R: &'static &'static i32 = &&I;

fn aux<'a, 'b, T>(_: &'a &'b i32, arg: &'b T) -> &'a T
{
    return arg;
}

fn make_everything_static<'a, T>(arg: &'a T) -> &'static T
{
    let f: fn(_, &'a T) -> &'static T = aux;

    return f(R, arg);
}

fn foo() -> &'static i32
{
    let a: i32 = 0;

    return make_everything_static(&a);
}

fn main()
{
    let res: &i32 = foo();
    
    println!("{0}", *res);
}

Все, раст плохой язык, он плохо меня защитил, а его компилятор написан неосиляторами, пойду поплачу (нет).
Эм, простите, я сломал логику совместимости Boost 1.70 и СMake 1.15, когда версией ранее флаги нормально вычитывались, а потом вдруг перестали?
UFO just landed and posted this here

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


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

IMHO, люди перестали понимать, в чём суть Си. Си — это ассемблер, а не Haskell. И он должен позволять программисту описывать всё то, что может исполнять процессор. Если под const выделена ячейка памяти в runtime, и если процессор может туда записать, Си не должен оказывать большого сопротивления программисту в желании эту записть осуществить.

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

Си он не про то, чтобы теоремы в интуиционистской логике доказывать, а про то, чтобы создать стабильное системное окружение для работы тех самых интуициноистских пруверов. Глупо предъявлять к Си те же требования, что к Coq или Haskell.

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

Да и потом, современный уровень развития инструментов программирования позволяет не писать на Си вообще всё. Он требуется для критичных циклов или для нестандартной низкоуровневой работы в условиях ограниченных ресурсов. Со всем остальным хорошо справляются высокоуровневые языки c JIT-компиляторами.

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

Ну, в С, например, нет циклических сдвигов, которые в процессорах есть очень часто. И многих специфических вещей типа POPCNT или CLZ тоже нет. И что делать?
Хорошо, если компилятор догадывается заменить функцию одной инструкцией, но он ведь не обязан.


А compiler-specific вещи — не часть языка, они не стандартизированы...

Для этого есть встроенный ассемблер. Хотя многое стало настолько широко распространенным…
Это перевод, сделанный злым роботом? И да, си умер. Единственным проектом на си осталось ядро линукса.
То, что вы чего-то не видите, не означает, что его нет. Си окружает вас точно так же, как линукс.
  1. Я пишу на Си с 1985 года. Скорее всего, большинство участников дискуссии родились позже, чем я первый раз запустил cc.

  2. Я написал на си более пары миллионов строк. Я писал на нём всё. Вообще всё. Ядро ОС, Яндекс Маркет (да, первая версия написана на чистом си в одно лицо), графику и СУБД, компиляторы и интерпретаторы, картографию и прикладной десктопный софт.

  3. Я до сих пор иногда пишу на Си. Ровно для того, чтобы иметь право сказать следующее:

  4. НИ-блядь-КОГДА, НИКОГДА и НИ ПРИ КАКИХ УСЛОВИЯХ кроме приставленного к голове ствола НЕ ПИШИТЕ НА СИ. Единственное исключение - это когда у вас ардуино и памяти два килобайта. Но это и есть приставленный к голове ствол.

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

  6. После этого у Вас исчезнет: А) херовая переносимость. Код на Си ПЛОХО переносим. Напомню - я пишу на нём почти 40 лет и помню, когда Си стал первым переносимым языком. Так вот - 40 лет таки прошло и он стал худшим по переносимости из всего, что есть на свете. Б) война с типами (какого размера у нас int?) В) война с инклудами (втащил библиотеку, она втащила инклуды, и они с твоими несовместимы) В) этот КАБЗДЕЦ с ручной аллокацией памяти, который вынуждает программера строить угробищные конструкции из структур данных потому что всё время надо думать, кто и как это будет освобождать. А не как это ДОЛЖНО быть устроено по уму. Г) вот эти лютые дыры в работе с памятью, которых в си не может избежать никто. Никто, блин. Д) Появится шикарный малтитрединг с широченной поддержкой в библиотеках и фреймворках. Е) Фантастическое количество библиотек, фреймворков и готового кода. Да, сильно больше, чем на Си. Если иметь в виду реально работающий, а не просто написанный код. И если иметь в виду затраты на втаскивание. Втащить в яву библиотеку - от 15 минут до часа. В Си - от часа до года. И втащится только половина. Половина собирается не так, не тем, тащит несовместимые либы не тех версий или просит для сборки ещё половину вселенной.

  7. Ну и да. JIT давно уже генерирует более эффективный код, чем статический компайлер. Уже хотя бы потому что постоянно профилирует исполнение программы. На реальных данных. А учитывая несравнимо более высокую читаемость программ на Яве после переписывания почти автоматом получится сделать рефакторинг, который всё ещё сильнее упростит и, вероятно, ускорит.

  8. На ++ тоже не пишите. Если карету 40 лет обвешивать молдингами и красить золотой краской она не станет звездолётом. А станет обвешанной хренью каретой. Опять же, это Вам говорит человек, который в 1988 прыгал от потолка, когда удалось добыть первый компилятор С++ и статью с описанием языка. Просто, опять же, 35 лет прошло.

  9. Если ваша религия не позволяет на Яве (что глупо, но ок) - пишите на Го. Это идеальная работа над ошибками - на выходе имеем тот же Си, но без дыр, без галиматьи. Этот язык, правда, устарел лет на 30 и в целом отражает образ мысли создателей Си: ООП зло, но без него никак, так что мы его добавим в язык, но через жопу, и сделаем вид, что ООП у нас нет. Эксепшены мы делать не умеем, поэтому они тоже зло и вы будете писать x, err = func(); if( err != nil) через строку и мы это объявим правильным подходом.

Ну то есть да, Вы отчасти правы - существует секта "Мы любим Си", которая всё ещё на нём зачем-то пишет. Но поскольку разработка на Си раз в 10 дороже разработки на той же Яве при худшем качестве результата, то существовать такая разработка может только в убытке, который покрывает какой-то обманутый технарями человек. Который или поймёт, что так не надо, или обанкротится.

"Согласно рейтингу языков программирования. PYPL (PopularitY of Programming Language) на основе данных Google Trends за январь 2023 года, в первую двадцатку популярных языков входят: Python, Java, JavaScript, C#, C/C++, PHP, R, TypeScript, Swift, Objective-C, Go, Rust, Kotlin, MATLAB, Ruby, VBA, Ada, Dart, Scala и Visual Basic. "

Не обманывайте себя. Пятое место тут - это поддержка старых проектов. Код живёт очень долго. Но - таки умирает. Новых проектов на Си не запускают. И - я планирую при жизни увидеть ядро Линукса не на Си.

Новых проектов на Си не запускаoют.

Вот тут - увы и ах. Прямо сейчас копаюсь в реально большом и важном проекте проекте, который написан на C начиная с 2018 (приблизительно), сетевая часть управления к транспортной железке (телеком, далее NDA). Проект действительно важный, счёт пользователей идёт на миллионы. Причём для связи с HAL там отдельная внутренняя сеть, так что тот C был не в тему, Go подошёл бы в разы лучше. Но - у кого-то там жуткая инерция мышления, что ли, или просто нанятые представители одной населённой страны иначе не умели. C, кстати, компилируется с -O0. Go точно был бы лучше:) До кучи надо сказать, что там ещё Yocto, и бутерброд из минимум трёх слоёв на некоторых пакетах вынуждает делать в патч-слоях патчи на патчи, иначе народ не справляется. Боюсь потерять последние волосы...

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

Sign up to leave a comment.