All streams
Search
Write a publication
Pull to refresh
88
0
Александр Мещеряков @freecoder_xx

Rust разработчик

Send message
Принципиальная разница в контроле за валидностью ссылок/указателей.

Да, и это действительно принципиальная разница. Насколько я знаю, умный указатель в C++ нельзя сделать для стекового объекта в общем случае. Ну и плюс всегда есть возможность использовать сырые указатели и ссылки, преобразовывать их в целые числа и обратно и т.п. Так что в полной мере C++ не защищает от висячих ссылок, в отличии от языков с GC и safe Rust.

Во-первых, в C++ управление памятью такое же, как и в Rust-е. Как бы вам borrow-checker не грел душу, но управление памятью такое же.

Напомните, как C++ разруливает времена жизни ссылки и объекта, на который она указывает? Также, как и Rust?

было бы крайне тяжело и дорого разработать на языках без GC, если вообще возможно

Уточнение: на языках без автоматического (ну или "полуавтоматического") управления памятью и с UB на каждом шагу.


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

Потенциал — есть, но будет ли он раскрыт? Покажет время и действия тех, кто сегодня выбирает Rust для своих проектов.

И тем не менее, многие крупные системы, написанные на Java, пытаются решать связанные с ней проблемы регулярными перезапусками.
Тем не менее, вы хотите сравнивать Rust с Kotlin/C#. В этих языках полноценный GC, в Kotlin к тому же еще и null safety, насколько я помню, присутствует. Поэтому в плане прикладного программирования Rust мало кому интересен, в отличии от Kotlin-а.

Интересная ситуация. Как уже было сказано, в большинстве типичных прикладных задач автоматического управления памятью Rust'а должно быть достаточно (без циклических ссылок). А для больших и сложных приложений, уже ощутимо преимущество в производительности перед GC и контроле за выделением/освобождением памяти + возможность писать unsafe-код. Этого сильно нехватало в Java. Так что я бы не торопился с выводами.

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

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

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

Все, что передается макросу на вход — это синтаксис, дерево токенов. Семантический смысл он обретает только в раскрытии макроса. Поэтому, если переданный синтаксис в раскрытии не используется, то компилятору совершенно фиолетово, что он из себя представляет по смыслу:


macro_rules! foo {
    ($($t:tt)*) => {};
}

fn main() {
    foo!(Fuck your semantic!);
}

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

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

Где вы вычитали такое? Сами придумали, сами разоблачили :)


В Rust есть безопасное подмножество, которое практически не содержит UB. В С++ вы можете иметь такие же гарантии для произвольного участка кода?

Все, что я хотел сказать, я уже сказал, а именно: сторонники Rust-а автоматически приравнивают UB, существующие в C++ном коде, к обязательно и неизбежно возникающим багам. Что вовсе не так.

Спасибо, Кэп. Более того я скажу, само возникновение UB — формально, не обязательно приводит к багам (ибо оно "неопределенное"). Проблема, о которой говорят вами ненавистные сторонники Rust-а — это то, что баги в таком коде могут появиться легко и незаметно. Вы с этим спорите? Если нет, то вопрос закрыт. А читать ваши сетования на сторонников Rust-а с выдуманными же вами взглядами — как-то совсем кисло.

Вы не понимаете, что есть поведение "стандартное" (не важно, чем оно определено: действительным формальным стандартом или даже просто договоренностью) и "нестандартное", то есть известное ошибочное поведение.


При этом, если вдруг UB возникает в "стандартной" части программы, то это — ошибка компилятора. Но если оно возникает в "нестандартной" — то это считается нормой. Ибо за пределами "стандарта" компилятор снимает с себя ответственность за что бы то ни было.


В Rust есть явная, четкая граница между этими двумя мирами, в C++ — такой нет.


Если, например, gcc или другой компилятор несколько уточняет стандарт C++, то есть выдает дополнительные гарантии там, где стандарт языка от них отказывается — если такие дополнительные гарании компилятор действительно дает, а не просто мы полагаемся на текущую его реализацию — то да, корректнее будет сравнивать тогда не C++ vs. Rust, а GCC C++ vs. Rust (оставляем за скобками тот момент, что человек может писать на GCC C++ при этом думая, что он пишет на C++, и связанные с этим проблемы в будущем).


Но меняет ли это ситуацию принципиально? Является ли GCC C++ — действительно безопасной версией C++, лишенной UB или явно ограничивающей его от остального кода? Только это обстоятельство принципиально может отличить безопасность GCC C++ от C++ как такового.

про макросы — ваш сочувствующий съехал на «синтаксическую составляющую», например, и что это нормально

Конечно. Макрос принимает просто токены. Если вы эти токены внутри макроса игнорируете, как элементы синтаксиса, то никакой ошибки компиляции не будет и быть не должно.

Конечно, спасибо за перевод, но качество оного — так себе :/
п.с. вообще неприятно вести с вами (растовиками) дискуссии. Вы пытаетесь навязать видение мира, в котором ни одна из программ на с++ не работает, а любая попытка его опровергнуть заканчивается ничем кроме пары минусов в карму.

Не знаю, о ком вы говорите и кто минусует. Лично я еще ни одного минуса "плюсовикам" не выдал. В плюсах разбираюсь слабо, поэтому обычно дискуссии Rust vs. С++ читаю c интересом. Так что обобщать и всех мазать одной краской, думаю, не стоит.

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

Языки семейства ML и Haskell, например, входят в ваш десяток? Может быть те, которые вы можете читать бегло — это всё вариации примерно одного и того же языка (или двух)?
Мало библиотек — это, конечно, плохо. Но с другой стороны — у вас есть много возможностей, чтобы создать свою библиотеку или стать мейнтейнером существующей, принести пользу сообществу и прославиться :)
Ну «дыра» — это громко сказано. Из-за того, что может быть кто-то недопонял или забыл, что макросы работают на синтаксическом, а не семантическом уровне, сразу злорадствовать о дырах… такое себе. Естественно, от подобных логических ошибок никакой компилятор не защитит, и тесты писать нужно, хотя бы простейшие.

И ведь подумал, что надо дописать: "хотя с документацией в Rust все в порядке", но не стал. А зря :)

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity