Comments 27
есть мануал для ада как писать безопасный код
https://habr.com/ru/articles/469671/
https://dwheeler.com/steelman/steelman.htm
Спасибо!
Это действительно максимально близко к тому, о чем идет речь.
Очень абстрактно.
Можно ли безопасно и эффективно реализовать на С++ с вашей memsafe-библиотекой или на newlang эту модель данных для редактора карточек?
Будет ли она чем-то лучше стандартного С++ или JS?
надо было почитать мануал для ада
Перед разработчиками не стояло задачи создать универсальный язык, поэтому решения, принятые авторами Ады, нужно воспринимать в контексте особенностей выбранной предметной области
Для удовлетворения требованиям надёжности язык построен таким образом, чтобы как можно большее количество ошибок обнаруживалось на этапе компиляции. Кроме того, одним из требований при разработке языка была максимально лёгкая читаемость текстов программ, даже в ущерб лёгкости написания[7]. Результатом такого подхода стал несколько «тяжеловесный» синтаксис и множество ограничений, отсутствующих в наиболее распространённых языках общего назначения (таких как Си и C++), например, та же строгая типизация. Это привело к формированию представления об Аде как о сложном, малопонятном и неудобном в использовании языке[8].
есть мануал для ада как писать безопасный код
https://habr.com/ru/articles/469671/
https://dwheeler.com/steelman/steelman.htm
Спасибо!
Это действительно максимально близко к тому, о чем идет речь.
но ада это другой язык, например, скорость если смотреть по бенчу, я смотрю на дебиан бенчмарк геймс, фанкуч редукс, например у С 2.15, у Ада 9.15, как тогда при безопасности невелировать скорость, например
например, можно предоставить удобный синтаксис, окей, но скорость, вот например, уходить от С или указателей или что-то в этом роде накладывает в другом каком-то месте возможно рост чего-то, типо плавающего процента
тоесть получается по билдам если смотреть если маг это стекло, он оправдано имеет такой контроль, потомучто за ним надо следить, если мы уходим в танковый жир, мы что-то другое делаем, чтобы сопротивляться магу, в тот же момент мага можно поймать, но маг имеет контроль и им надо контролировать, вот скорость это помойму та самая ситуация, скорость делает язык узким, потомучто его надо контролировать
поидее если язык будет гарантировать безопасность, аля разыменование значений и подставка в адрес, то это поидее нужен супер компьютер, сегодня из имеющейся еффективности и выходящей мощности и доступности, придумали ту бумажку, которой все пугают, не буду с ней спорить наверно експертам виднее, но факт, то что витает в воздухе по выходной мощности и нагрузке, несоизмеримо с просто взять и отправить значение в адрес и посмеятся на нуле
как я понял вся крамола вокруг этого нюанса
*p=&a;
продолжу, так вот придумали ту бумажку, так с гарантийным языком, тоже будут нюансы, повысится еффективность и опять пересмотр безопаности, тоесть вчера показали те трюки, а может там не только такие, ну и так далее, это действительно видимо прям изучать наверно нужно
предсказуемость и надёжность - это звучит просто, но как я понял модель перегонки кланга или какого-нибудь рю, посмотреть схему работы - вообще не очевидно
Можно пойти третьим путём и написать компилятор, который будет делать то же, что и компилятор Rust - проверять статические инварианты и при этом сам будет являеться формально-верифицируемым - аналог CompCert, но для плюсов.
Ну и есть другие нюансы касательно предлагаемой безопасности, которые не учтены. Для простых програм RAII обычно достаточно, но для высокопроизводительных это может быть довольно расточительным - одна только фрагментация сколько шуму наделает.
Другой момент связан с огромным количеством способов достичь UB - забыл проинициализировать bool - лови UB, шагнул итератором больше положенного - лови UB, Cкормил рэнжи в неправильном порядке - лови ещё приколов для отладки, хоть и не UB. И вот эти моменты сложно обезопасить без переделки языка.
Спасибо, хорошие замечания.
Чтобы проверять статические инварианты писать компилятор не нужно. Можно сделать плагин для существующего компилятора
Про высокопроизводительные программы с RAII сказать ничего не могу. Все дело в реализации алгоритма. Подозреваю, что в этом случае можно реализовать алгоритм, которые очищает память объектов только при завершении работы (аналогично, как это делается для пула потоков).
Другой момент связан с огромным количеством способов достичь UB ...
Большинство этих UB успешно ловится анализатором во время компиляции (ссылку я давал чуть выше)
Подозреваю, что в этом случае можно реализовать алгоритм, которые очищает память объектов только при завершении работы
Именно так. Пулы объектов, арены, генерационные индексы, кастомизированные аллокаторы и прочие data driven прелести. Они, конечно, тоже имеют отдельный класс проблем, осложненный всё тем же отсутвием владения и времени жизни, но всё равно формализуется несколько проще т.к. границы определены некоторым набором классов имплементации всей этой системы. Есть, конечно, ещё вот такой доклад, где в некотором виде эти механизмы воспроизводят на шаблонах, но это скорее эксперимент нежели production ready решение, по крайней мере пока.
У вас же в readme RAII стоит первым принципом, поэтому обратил на этот момент ваше внимание. Отдельно стоит упомянуть подход используемый в go/zig/jai/odin с defer освобождением - фактически ещё вариант RAII, но более явный и чаще более чистый в сравнении с пелёнкой объявлений шаблонных параметров в умных указателях.
Чтобы проверять статические инварианты писать компилятор не нужно.
тут скорее это необходимо для формальной верификации всей системы. авторы, писавшие compcert рассказывали, что отправили немало баг репортов в компиляторы, которые естественным образом всплыли при написании собственного компилятора. Где-то генерация была кривая, где-то поведение компилятора было некорректным и приводило к некорректному поведению в уже скомпилированных програмах. Доставалось и GCC и Clang, однако это только часть про язык С. Спецификация языка С++ примерно в 10 раз больше чем у C и произведение множеств фич тоже растёт нелинейно, что может намекать о наличии аналогичных невыявленных багов. Такое простым плагином не решишь. TLA+ в теории можно сделать плагином, но вот насколько оно нужно тоже вопрос.
Отдельно стоит отметить, что похоже не все компиляторы имеют возможность использовать плагины. Clang/gcc имеют инфраструктуру, а msvc насколько я понимаю - нет, но это не точно. Насколько имеющиеся системы плагинов feature complete по сравнению друг с другом тоже вопрос открытый.
так раст в итоге кладёт ответственность на разработчика предоставляя в сухом остате еще хуже синтаксис, и местами медленнее С, потомучто для полной безопасности надо удалить указатели из программистского пользования языком, тоесть этот путь с чекингами в компил тайм или система компилятора, которая запрещает ничего не упрощает по факту, на С++ минимально это можно повторить, но для полного повтора это удаление указателей, и да если удалить указатели ради безопасности мы теряем механизм со скоростью, и оказываемся где-то около адa/java
C++ это другой язык и С другой, уб это что-то наподобии, когда собака отбежала от хозяина на 200 метров, и хозяин понимает гарантии минимальны, в итоге мы либо вынуждены все проверять и всегда рядом быть, либо полагаться на собаку - что не несёт гарантий во времени это и есть самое настоящее УБ, тоесть уб еще шире поидее как класс проблем
sudo-rs, tar, core-utils - это всё показатель тех уб тоже, их CVE, переписали в итоге оказалось не безопасно, а в примере целая ОС на Раст, но всё равно взялись переписывать, и тут мне щас начнут обьяснять наверно, что это другое
Удалить указатели из С++ не возможно, так как это основа языка. Но это и не нужно, достаточно реализовать контроль их использования только как автоматических переменных с инвалидацией при изменении объекта.
как автоматических переменных с инвалидацией при изменении объекта
К сожалению это невозможно в плюсах. Да и вообще, сделано только в Го и, возможно еще в Шарпе
Почему невозможно? Вот пример реализации https://github.com/rsashka/memsafe
предоставляя в сухом остате еще хуже синтаксис, и местами медленнее С
совершенно не согласен. на расте гарантированно можно выражаться на порядок выразительнее при одинаковой функциональности. это не считая, что базовые потребности закрыты из коробки - вспомните хотя бы сделать динамический массив на си не переизобретая в очередной раз толстые указатели и не городя кучу макросов для добавления. Новый проект - новая копипаста очередного килобайта. А его ещё надо в сборочную систему добавить, что тоже +1 уровень боли.
Ну, а про медленнее - вы определённо ошибаетесь. Какие флаги, какой компилятор и прочее будет влиять на время исполнения и публичные бенчи обычно показывают статистически колебания в пару процентов в любую из сторон, что фактически приводит нас к третьему варианту лжи.
sudo-rs, tar, core-utils - это всё показатель тех уб тоже, их CVE, переписали в итоге оказалось не безопасно
потому что безопасность складывается из нескольких классов ошибок и большинство CVE завязаны на ошибках проблем с обращением к памяти - buffer overflow и use after free дают более половины этой цифры, а с остальными вариантами все 80%. То что Rust их закрыл совершенно не означает, что остальные классы ошибок куда-то растворились. Поэтому удаление указателей тоже не спасёт, даже если мы готовы жертвовать скоростью.
а в примере целая ОС на Раст
в этом месте не очень понял что вы хотели этим сказать. Не считая активного развития ржавчины в embed секторе, то бишь недоОС на голом железе, существует как минимум ещё четыре OS ядра на голом Rust, которые нацелены на разного уровня безопасность и производительность. Тот же Амазон на своём Firecracker сэкномил себе немало средств, хотя казалось - бери какой-нибудь alpine и нос не вороти.
тоесть уб еще шире поидее как класс проблем
Собственно результат UB и расфасовывают по классам ошибок. Самые популярные опять же оказываются в категории ошибок с памятью - double free, null ptr dereference и тп. Integer overflow/underflow оказываются в собственном классе и для си/с++ механизмы работы с ним настолько же UB, насколько и само переполнение. Можно полагаться на поведение конкретных компиляторов, но никто не гарантирует, что его не станут ломать позже - ибо на то он и UB.
Можно почитать блог мозиллы или хотя бы вику на предмет замены сишного кода на rust и результаты. Там и количество репортов о падений на рендеринге шрифтов сократили и ускорили работу с CSS просто потому, что смогли без боли использовать оба варианта параллелизма. Стало ли оно при этом безопаснее? Да не прям сказать чтобы сильно. Однако же.
Где купить такое стеганое одеялко, как на КДПВ? ))
очередное нагенерированное LLM ниочем
Не понятно какой практический вывод должен сделать читатель из вашей статьи.
Пример реализации гарантий безопасности при работе с памятью для С++ можно посмотреть в этом проекте
В плюсах наверное, это не исправить из-за акцента на максимальную производительность. Только ручное управление плюс статический анализ.
Но в D все переменные по умолчанию перевели на TLS. Ну и проблему беглых ссылок они пытаются решать. Но за это надо платить, либо времён исполнения, либо временем компиляции.
Так язык не меняется, просто на код с помощью статического анализатора накладываются дополнительные ограничения, но производительность остается такой же, как и была у С++.
О чем и речь. Без изменений синтаксиса или, тем более, парадигмы, каких то принципиальных результатов не достичь.
Только костыли в виде статанализа. Который несомненно полезен, но не все находит и имеет квадратичную сложность.
Измерение синтаксиса и изменение парадигмы, это не одно и тоже.
Я согласен, что удобнее всего менять парадигму и синтаксис одновременно (т.е. путем создания нового языка), однако прототип как раз и демонстрирует возможность изменения парадигмы на старом синтаксисе. Да, неудобно, но зато с сохранением обратной совместимости и возможностью плавного перехода на новую парадигму (или использования двух парадигм одновременно).
Поэтому в настоящий момент более актуальной становится не скорость создания ПО, а качество получаемого результата
Откуда взялся этот вывод?
Для одних областей это так и у меня тоже. Но точно знаю что во многих областях это не так. Там где царит FOMO и желание корпораций продавать вам brand new shit каждый год.
Гарантии языка программирования как основа безопасной разработки программного обеспечения