Pull to refresh
16
0

Пользователь

Send message

Если бы я делал, я бы делал так:
В каждой переменной хранится не только её значение но и история операций над ней (можно в компайл тайм). Дальше каждая операция добавляет ограничение на значение переменных. Если всё иммутабельно в функциональном стиле то должно работать. Например мы пишем m = a % b и мы знаем что |m| < b. В плюса это было бы тип int который хранит число, а тут ещё эту информацию (a<|b|) дополнительно храним в переменной m. Далее мы уже можем вызывать функцию f(x,y) которая принимает не только int, а некий x на который наложено ограничение что он меньше y как f(m,b).

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

Сколько времени можно будет сэкономить :)

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

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

А вообще как проверяется стандарт с++ на отсутствие логических дыр? Есть ли какое то доказательство что он не противоречит сам себе? Иногда такое впечатление что в него добавляют фичи метапрограммирования а только потом узнают о последствиях и всяких багофичах.

Разве в расте можно продлить время жизни? Как я понимаю это просто защита от dangling reference.

Изначальные поэмы вряд ли были из шедевров русской литературы, поэтому как раз в оригинале все отработало нормально;)

Автор не запускал код, потому что для utf-8 надо считать количество символов так


line[start..location].chars().count()

Иначе форматирование ^ съедет.


Ксати почем для си не включили подсветку синтаксиса или это хабр чудит?

Раст не настолько крут чтобы проверять алгоритмы хеширования на наличие легко-генерируемых коллизий :)

Почему вы взяли что там баг? Просто какое то кастование буферов, скорее всего будет ненужно когда завезут const generics наконец и будет нормальные GenericArray в std.

Заголовок спойлера
доктор откуда у вас такие картинки

Отвечу сам себе. Создание и удаление временного объекта для f(unique_ptr<T> p) лежит на стороне вызывающего. Поэтому в с++ реализация функции f не вызывает конструктор и деструктор. В расте происходит по другому, при f(p: Box<T>) ответственность за удаление объекта лежит на самой функции f поэтому мы видим dealloc в асм выхлопе. Естественно на всю программу количество new/delete в случае с++ и раст не изменилось (при условии что с++ компилятор выкинет delete nullptr для moved-out объекта). Далее было бы интересно подумать какие это дает плюсы и минусы для оптимизации сложной программы где есть много подобных вызовов (так же в случаях f(f(f(p)))). Хотя если всё заинлайнилось то по-идее разницы быть не должно.

Точно так же передадите значение в си функцию из раста.

вы упрощаете в своем примере, например тут описывается реализация arena https://exyr.org/2018/rust-arenas-vs-dropck/, и уже инварианты не такие тривиальные.


Я тоже написал на расте жсон/хмл/sql молотилку и тоже без ансейф и всё хорошо :)

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

Очевидно что можно писать вокруг каждого unsafe if-ы и проверять инварианты.


Но во-первых даже если так делать (но вдруг забыть) фактически (т.е. место в коде в котором нужен патч) ошибка будет в if-ах а не в unsafe. Т.е. уже история с грепом по unsafe это некое преукрашательство.


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


Но например в std большое количество unsafe, и доказать что там работает всё коректно т.е. внешний апи safe было не быстрой задачей. Тут кидали ссылку где-то выше (может и вы сами) на статью.


Теперь мы приходим к моему тезису изначальному "значит надо проверять всю программу" — естественно не прямо всю целиком, а какой то модуль или класс, в простых случаях действительно только функцию или только 5ть строк, где происходит заворачивание ансейф в сейф.

А еще они имеют рантайм оверхед.
https://godbolt.org/z/mHcFeM

Кстати интересный пример. Как оно в c++ работает? Почему компилятор выкинул delete, потому что я не вижу heap аллокации тут.

Eсли бы я хотел иметь проверку idx < arr.len() прямо перед обращением к индексу я бы сразу использовал safe метод!


Нет, не надо, нам же не важно, откуда оно пришло, нам важно, какое значение оно принимает.

У вас if снаружи unsafe внутри unsafe важно.

открываем первый пример


if idx < arr.len() {
        unsafe {
            Some(*arr.get_unchecked(idx))
        }
    }

unsafe ничего не знает про idx, он может прийти откуда угодно, значит надо проверять всю программу.

Information

Rating
5,066-th
Registered
Activity