[HN Gopher] What it feels like when Rust saves your bacon
       ___________________________________________________________________
        
       What it feels like when Rust saves your bacon
        
       Author : lukastyrychtr
       Score  : 186 points
       Date   : 2022-06-24 06:43 UTC (16 hours ago)
        
 (HTM) web link (smallcultfollowing.com)
 (TXT) w3m dump (smallcultfollowing.com)
        
       | rs_rs_rs_rs_rs wrote:
        
       | Animats wrote:
       | _" Each method is defined on this Context type that carries some
       | common state, and the methods tend to call one another."_
       | 
       | This is classically a problem of GUI systems, where you have a
       | large number of interlinked on-screen objects constantly
       | undergoing modification.
        
         | BiteCode_dev wrote:
         | And hence the general recommendation of having a single
         | direction in your input/render cycle:
         | 
         | - wait for input
         | 
         | - a dispatcher take any input and turn it into a queue of model
         | update actions
         | 
         | - pop queue to perform latest model updates.
         | 
         | - trigger a full tree rendering, passing the new model
         | 
         | - start again
         | 
         | So:
         | 
         | - the model is a dumb static data structure
         | 
         | - the dispatcher is the responsible for model updates and is a
         | single entry point for the data flow
         | 
         | - the UI and the model don't know about each other
         | 
         | That what ELM, react and so on do now. Monodirectional MVC.
         | It's hard to optimize the rendering though, but it's way easier
         | to reason about when concurrency gets high.
        
           | mejutoco wrote:
           | > - trigger a full tree rendering, passing the new model
           | 
           | I agree the Elm model makes it easy to reason about it.
           | 
           | Just because we pass "the state of the world" each time
           | instead of mutating it, does not mean that we need a full
           | tree rendering. That is an implementation detail.
           | 
           | We can update just the relevant part. If we think of it
           | mostly as pure functions a lot of it is easier to memoize and
           | -- for same input -- it is possible to return the same output
           | straight away.
        
             | BiteCode_dev wrote:
             | That's what I mean by hard to optimize. Memoization is hard
             | to get right, because if you compare only by value, it can
             | be slow, but if you compare by identity, the cache can take
             | a lot of memory.
             | 
             | And of course, forcing a purely immutable model comes with
             | its own unique challenges.
        
       | lbriner wrote:
       | I have only a small dabbling in Rust and it was to create a
       | Postfix milter. What was awesome was that someone had already
       | written a Rust crate so that I didn't have to do anything too
       | horrific. The compiler on Ubuntu just worked as expected but, of
       | course, as something that is not standalone, Rusts strong type-
       | checking did not save me from writing something that didn't work.
       | 
       | Part of the confusion is the very confusing (for a noob)
       | difference between String and &str and as someone who has written
       | C and C++, I don't have a problem with understanding references
       | and addresses but I didn't find a very good explanation. This led
       | me to writing code using the only way I could get it to compile
       | that didn't crash at runtime (which was nice!) but it also didn't
       | work.
       | 
       | The second issue was that being something plugging into an
       | external daemon, at the interface level, we were getting a raw
       | pointer and had to convert it into a string to use it. I tried so
       | many combinations but couldn't get it to work but thanks to the
       | maintainer of the Rust crate (who obviously knew what he was
       | doing) he told me where my code was wrong and I fixed it.
       | 
       | So I guess good in that there were probably no horrific bugs,
       | although this is much like C# or possibly Java. But yes, the
       | strong checking doesn't stop things from not working.
        
       | darthrupert wrote:
       | Rust's safety features have never been its main selling point for
       | me. Modernity and (recently) momentum are. That it's impossible
       | to author certain classes of bugs is a nice bonus.
       | 
       | That said, I never want to see another rounding bug in financial
       | statements that happened because some piece of code implicitly
       | converted a string to a float and it kinda almost worked every
       | time. To quote a cliche, I'm too old for that shit.
        
         | darthrupert wrote:
         | (Probably float to string and back, actually. Some mess like
         | that anyway)
        
       | cobbzilla wrote:
       | When I was first learning Rust, it was exactly this sort of
       | lifetime issue that tripped me up and frustrated me, until I
       | finally saw the light and understood how things work.
       | 
       | Yes, the article is overly technical and detailed, but it
       | captures very well the eureka moment of understanding Rust's
       | memory management. Some aspects are subtle yet profound.
       | 
       | I am always happy to take a little more pain at code-writing and
       | compile-time in exchange for more safety guarantees at run time;
       | Rust is great in this regard.
        
       | shuger wrote:
       | This article is super overcomplicated. All it had to say was that
       | rust tells you when you keep reference to on stack variable after
       | it goes out of scope. Context provided adds nothing.
       | 
       | I must say - as someone who doesn't use rust - I haven't had this
       | type of issue in years, and when I did it wasn't hard to debug.
       | You get corrupted data, set data breakpoint and in the provided
       | example you will see it being modified by unrelated operations on
       | stack. From there there is only one conclusion. Authors reactions
       | seems to be a bit exaggerated.
        
         | atoav wrote:
         | It all depends on the complexity of your application. The type
         | of guarantees Rust offers in my experience becomes
         | exponentially more useful as your application grows in size.
        
           | DrBazza wrote:
           | Just because Rust, in particular, compiles successfully,
           | that's no guarantee that the code isn't complex and difficult
           | to understand. I can write a complex badly designed app in
           | any language. Similarly I can write simple well designed
           | large applications in any language too.
        
             | ChadNauseam wrote:
             | Yeah, but that doesn't mean all languages are created equal
             | in that department. Let's take this pseudocode:
             | int a = 0;         if (findindex(mylist, myvalue, &a)) {
             | // dostuff with a         }
             | 
             | Here, findindex returns false if it can't find the value.
             | The problem is that there's nothing forcing you to use the
             | if, you can just forget it and you'll be left with
             | incorrect code. In Rust, this type of error is impossible
             | to make by accident, because the findindex function would
             | return an Option, and you have to explicitly handle both
             | cases (or explicitly say you don't care about one of the
             | cases).
             | 
             | Things like that, along with the lifetime system, make it
             | easier to write good code. It's like saying that it's
             | possible to destroy your foot with a shotgun and with a
             | pencil - it's possible, but it's a lot easier do to by
             | accident with the shotgun.
        
             | Daishiman wrote:
             | This fallacy gets repeated over and over again and it
             | doesn't make it any less false.
             | 
             | Languages are tools and some tools are actually better-
             | built than others. If we can claim that a language like
             | Brainfuck makes writing clear code extremely difficult, and
             | Python or Rust make writing clear code easier, we've
             | already established that there's a spectrum for language in
             | expressiveness and clarity.
             | 
             | Eliminating entire classes of bugs makes for better
             | understanding.
        
           | lelanthran wrote:
           | > It all depends on the complexity of your application. The
           | type of guarantees Rust offers in my experience becomes
           | exponentially more useful as your application grows in size.
           | 
           | Sure, but the development pattern that get used for larger
           | applications typically don't benefit from Rust's additional
           | safety; for one you're going to be using a garbage collected
           | language.
        
             | MaulingMonkey wrote:
             | > for one you're going to be using a garbage collected
             | language.
             | 
             | I wish it were true, but promise you it is not. As a
             | counterpoint, I point to most "AAA" gamedev and OS
             | development.
             | 
             | In gamedev it's even a bit flipped: The smaller indie
             | gamedevs can pay the GC hit for Unity's C#, web JS,
             | actionscript flash back in the day, etc. - not much working
             | data, not much garbage. Larger scale titles start missing
             | vsync and having horrible stuttering when GCs are thrown
             | into the mix too brazenly - they're still used on smaller
             | scales (embedding browser tech for UI, limited scope
             | scripting, etc.) but they have a lot of native, non-GCed
             | code.
        
           | MaulingMonkey wrote:
           | This indeed. Small local console app running on trusted data?
           | Maybe an hour to track down some memory corruption if you're
           | particularly unlucky, in which case shuger's kind of got a
           | point: who cares?
           | 
           | Large network-exposed app? Individual memory corruption
           | heisenbugs have taken me _weeks_ to track down (and weeks
           | before that for QA to create a reliable repro for) - a needle
           | in a huge haystack. They often predate my employment - having
           | lurked semi-silently for who knows how long causing who knows
           | how many unreported crashes. When release dates slip because
           | of bug backlogs filled with memory safety related crash bugs,
           | when ~70% of many vendor CVE reports are down to memory
           | safety issues [1][2][3], and when you personally have to deal
           | with the fallout of all that: shuger 's point completely and
           | utterly evaporates.
           | 
           | [1] https://msrc-blog.microsoft.com/2019/07/18/we-need-a-
           | safer-s...
           | 
           | [2] https://www.chromium.org/Home/chromium-security/memory-
           | safet...
           | 
           | [3] https://langui.sh/2019/07/23/apple-memory-safety/
        
         | SloopJon wrote:
         | > All it had to say was that rust tells you when you keep
         | reference to on stack variable after it goes out of scope.
         | 
         | The author isn't just telling you that Rust is awesome because
         | it tells you something, he's acknowledging the frustration in
         | learning how to listen to the compiler.
         | 
         | It's kind of like Jerry Pournelle describing the ups and downs
         | of USB by documenting an epic journey that all started with
         | trying to scan some handwritten notes for his next novel using
         | a Canon scanner he borrowed from Alex that he's just now
         | getting around to reviewing, because the pins of the parallel
         | port are too bent to use the old Epson. Okay, so maybe it was a
         | little overcomplicated.
        
         | est31 wrote:
         | > You get corrupted data, set data breakpoint and in the
         | provided example you will see it being modified by unrelated
         | operations on stack.
         | 
         | That's provided that you can even reproduce the issue well,
         | especially in an instrumented build which might be way slower
         | than the non instrumented one. Often you get bug reports like
         | "crash after one hour of usage" where basically every feature
         | of the app has been heavily used by multiple users. Rust
         | applications might still crash but they crash safely, which
         | means your error messages are more meaningful.
        
         | ekidd wrote:
         | > _All it had to say was that rust tells you when you keep
         | reference to on stack variable after it goes out of scope._
         | 
         | That's the root cause, but it's not the interesting bit.
         | 
         | The code in the article comes from a production compiler. And
         | normally, the AST (abstract syntax tree) is a single data
         | structure output by the parser. Ownership is simple: the entire
         | AST has the same lifetime, and it's managed by a caller. This
         | should be easy, right?
         | 
         | But it turned out that there was a piece of code that
         | _sometimes_ "synthesized" extra, temporary AST nodes. And these
         | nodes had a shorter lifetime than the rest of the AST.
         | 
         | These are vicious bugs. You have some long-standing convention
         | about how things work, but one little piece of code makes an
         | exception (often for excellent reasons). Then _another_ module
         | decides to make an aggressive optimization that relies on the
         | original assumption. But that assumption is now true only 99%
         | of the time.
         | 
         | It's a communication failure, and it might take years to
         | actually turn into a bug. And that bug may manifest as
         | extremely rare memory corruption that shows up in automated
         | crash reports.
         | 
         | Running down this kind of phantom memory corruption is one of
         | the most frustrating things I've ever done. It often involved
         | spending weeks staring at minidumps, looking for interesting
         | patterns in crashes. There's that horrible moment when you
         | realize that 20% of your crashes occur within a thousand
         | instructions after a particular font-rendering function reports
         | an error, accidentally corrupting the exception-unwinding
         | machinery.
         | 
         | And sure, I get it. Maybe your team is simply good enough that
         | nobody ever makes a mistake like this. But if so, they're
         | exceptional. I've worked on amazing teams that still get bitten
         | by subtle miscommunications and misunderstandings.
        
         | ArrayBoundCheck wrote:
         | It's unfortunate how many upvotes this got from the title
        
         | cbarrick wrote:
         | Earlier this month we integrated a C++ library written by my
         | team with a server written by another team.
         | 
         | We saw the data corruption, and we knew it was a reference
         | issue, but it took quite a bit of effort to track down. The
         | cause was confusion around string_view and string&, with
         | different behavior when you pass each to a new thread.
         | 
         | Rust would have caught this much earlier and saved 3 days work.
        
         | lelanthran wrote:
         | Agree; this is not an issue that slows down my development or
         | bughunts.
         | 
         | You can get a long way towards safety without learning Rust.
         | It's those rare cases that will get you.
         | 
         | It's a trade-off; take the time to learn the language and
         | deliver later, or just use what you already have to deliver a
         | product now.[1]
         | 
         | [1] During a Rust discussion some years back, when I was at a
         | different company, on a specialised and large-ish product
         | written in C++03.
         | 
         | I went through about 3 years of tickets (limited to only the
         | bugs reported). No open ticket was older than a few weeks. Out
         | of maybe 1000 bugs, only a single one was something Rust would
         | have prevented. I would think that most mature products will
         | have similar stats, so the trade-off is not as obvious as it
         | looks to be on the surface.
         | 
         | Deliverables matter.
        
           | nemothekid wrote:
           | > _I went through about 3 years of tickets (limited to only
           | the bugs reported)_
           | 
           | This statement is meaningless without any insight on how bugs
           | were created. If the bug reports exclusively dealt with
           | "happy-path" or "business logic QA", then of course you won't
           | see any CVEs. Did the use of fuzzers or address sanitizers
           | create bug reports? Were these tools even used? If not, the
           | claim that only one of 1000 bugs were memory safety issues
           | isn't credible; you weren't looking for them so of course you
           | didn't find them.
           | 
           | I think it says a lot when almost every C++ developer claims
           | to have a higher quality code base compared to say Linux or
           | Chromium when it comes to memory safety errors.
        
             | Daishiman wrote:
             | What is it about C++ as a community where most average devs
             | claim an inhuman level of proficiency but only the coders
             | with experience in real critical codebases have the
             | humility to claim that without extremely strict coding
             | practices and extensive use of fuzzers we're barely smarter
             | than apes at churning out safe code?
        
           | vgel wrote:
           | It probably depends on project type and how complex your
           | ownership models are, but that doesn't really track with
           | large projects having a majority of their CVEs be memory
           | safety issues that are far less likely in Rust[1] (e.g.,
           | https://www.chromium.org/Home/chromium-security/memory-
           | safet...)
           | 
           | [1] I say far less likely because obviously it's possible
           | with unsafe Rust, but I've never had one happen, seen one
           | happen in real code, or been affected by part of a dependency
           | tree having one.
        
             | snovv_crash wrote:
             | CVEs are a tiny, tiny fraction of bugs.
        
             | lelanthran wrote:
             | I'm not saying that a large number of CVEs _won 't_ be
             | prevented in Rust, I'm saying that so few bugs are CVEs
             | that the trade-off is not always worth it.
             | 
             | If you have 1000s of bug reports, of which 5 are CVEs, and
             | then have 3 of those 5 be preventable, most dev teams are
             | still going to consider the cost/benefit of going through
             | the pain of developing a long-term product in Rust, or of
             | switching to Rust altogether.
        
               | girvo wrote:
               | I suppose it comes down to risk assessment; if those CVEs
               | are critical "fix this now or the world catches fire",
               | then their relative infrequency seems to be outweighed by
               | their impact, no?
        
               | lelanthran wrote:
               | > I suppose it comes down to risk assessment; if those
               | CVEs are critical "fix this now or the world catches
               | fire", then their relative infrequency seems to be
               | outweighed by their impact, no?
               | 
               | No.
        
               | bschwindHN wrote:
               | > of which 5 are CVEs
               | 
               | Those 5 are just the ones you know about...
        
               | lelanthran wrote:
               | > Those 5 are just the ones you know about...
               | 
               | It's pointless making a cost/benefit analysis on things
               | that probably don't exist.
        
         | renox wrote:
         | I agree with you on the first point, but I totally disagree
         | with you on the second point: sure if you know how to reliably
         | reproduce an issue it isn't complicated to debug, but this kind
         | of issue can be difficult to reproduce, can create silent
         | issues..
        
         | bestouff wrote:
         | Yeah no. In my experience, when several people commit to a
         | common C/C++ codebase this kind of issue become really
         | exhausting when it happens more than once, and the symptoms may
         | be so subtle it's a bitch to debug.
         | 
         | Rust lowers your mental load. You spend more time being
         | creative and way less time debugging "obvious" (or not)
         | mechanical problems (reference not-on-stack-anymore variables,
         | use-after-free, concurrent write access and all kind of
         | compiler undefined behavior). That why garbage collected
         | languages are so successful (they let you concentrate on the
         | business logic) and for the first time it's available in a
         | system language.
         | 
         | Everything that can be done by your computer should be done by
         | your computer. You should leave your precious brain cells
         | available for the important stuff.
        
           | phendrenad2 wrote:
           | Nope. In my experience, Rust saves you from very common
           | obvious errors that junior programmers make, certainly not
           | 10x programmers who have been writing C for a long time. It's
           | great when you're starting out (which is why it's massively
           | popular with new graduates or people who are just learning to
           | program), but at some point it's questionable if the hand-
           | holding Rust gives you is worth the extra development time
           | overhead, more complex syntax, etc.
           | 
           | It also depends on what you're writing. If you're writing
           | cryptographic routines, or protocol handshaking, the
           | tradeoffs are heavily weighted in Rust's favor.
        
           | shuger wrote:
           | I work in probably what is considered one of the least "safe"
           | languages: C++
           | 
           | The issues that Rust is supposed to help with are simply not
           | what we spent time on. All the bugs reported are pretty much
           | exclusively root caused to "business logic".
           | 
           | From recent time I can recall only one that was a programming
           | mistake and not architecture/business logic related. It was a
           | missing break in a switch that already had some fallthroughs
           | so it didn't look incorrect at a glance.
           | 
           | I do understand what Rust is supposed to provide but in
           | practice it's simply an extremely minor source of bugs.
        
             | jackmott42 wrote:
             | I see many C++ programmers say stuff like this, and maybe
             | it is the case that studios exist which can do C++ without
             | mistakes related to memory management or sigils and so on,
             | but I also observe that:
             | 
             | 1. High quality teams like the Linux kernel team and
             | PostgreSQL, do periodically have serious security bugs that
             | are things Rust would have caught.
             | 
             | 2. I see sometimes C++ instructors making the same claims
             | you do and then spending half of a lesson tracking down a
             | memory mistake, (Casey Muratori) or in the same month a
             | tweet from a game engine developer saying they don't really
             | see the value of garbage collection and then tweeting about
             | how they spent 48 hours tracking down a memory mistake. (of
             | course, for a game engine that is what you have to do
             | sometimes!)
             | 
             | There are however valid questions, like if Rust slows down
             | your development say, 5%, would you get more net safety
             | from spending 5% more time testing/fuzzing c++ code
             | instead? etc.
        
               | melissalobos wrote:
               | > High quality teams like the Linux kernel team
               | 
               | Which very notably does NOT use C++.
        
               | csdreamer7 wrote:
               | Nor does Postgres.
        
               | 3a2d29 wrote:
               | > High quality teams like the Linux kernel team and
               | PostgreSQL, do periodically have serious security bugs
               | that are things Rust would have caught.
               | 
               | Safe rust would have caught. If you had to drop into
               | unsafe to do what they did, the serious security bugs
               | would still have happened.
        
               | jackmott42 wrote:
               | A fair point, though the few security issues in recent
               | years I've looked at were not the kind of thing you would
               | turn to unsafe rust for. But I've certainly not done a
               | broad enough sampling to say what % of cases are like
               | that.
        
               | 3a2d29 wrote:
               | To be fair, I am sure Rust catches a fair amount
               | (compared to C++ which would catch 0). I just think that
               | phrasing rust has having 0 memory errors can be a tad
               | inaccurate.
        
               | jesse__ wrote:
               | I'd venture that the development slowdown from using rust
               | is closer to 50% than 5%. Even just compile times
               | probably slow down that much, not to mention you have to
               | write (sometimes) as much as 10x code to express
               | yourself.
               | 
               | The specific exercise I have in mind is a lockless thread
               | queue. < 20 lines in C .. ~200 lines in Rust.
        
               | jackmott42 wrote:
               | I'm sure there is a ton of variance. I have done some
               | Rust projects where I run into absolutely no safety
               | complaints from Rust because it just isn't the kind of
               | code that does anything the borrow checker cares about.
               | For those development time ends up typically faster than
               | C/C++ due to various syntax and tooling niceties.
               | 
               | Other projects will really get into domains where you
               | have to work hard to satisfy the borrow checker and it
               | can slow you down a lot. In a real application you won't
               | be writing lockless thread queues for a big % of the
               | time. But then for a real application the compile times
               | will start to weigh on you more. (Though, C++ does not
               | always compile fast either unless some care is taken to
               | be sure it does)
        
               | Yoric wrote:
               | My anecdotal experience is the opposite.
               | 
               | I write code much faster in Rust than in C++. Part of it
               | is thanks to the type system - fewer opportunities for
               | dev errors means that I can produce code that is more
               | concise, spends less time handling runtime errors because
               | I can have static guarantees that they have already been
               | handled somewhere, etc. Part of it is #[derive(...)],
               | great documentation, Cargo and other QoL components of
               | Rust.
        
               | pkulak wrote:
               | A lockless thread queue (not entirely sure what that
               | would be, sorry; a queue in front of a pool?) seems like
               | the kind of low-level library that could be written with
               | liberal use of unsafe. No need to flagellate yourself on
               | the altar of compile-time safety.
        
               | kajaktum wrote:
               | >The specific exercise I have in mind is a lockless
               | thread queue. < 20 lines in C .. ~200 lines in Rust.
               | 
               | Do they have an equivalent API? Rust does have a hard
               | time explaining very, very low level stuff that you'd
               | have to do unsafe and various magicks. But once you get
               | the unsafe details right, the consumer API for them tends
               | to be extremely rigid and fool proof.
        
               | [deleted]
        
               | __jem wrote:
               | > The specific exercise I have in mind is a lockless
               | thread queue. < 20 lines in C .. ~200 lines in Rust.
               | 
               | Why is this your exercise you have in mind though? This
               | is such a bad argument. Like, yes, if you work at
               | doublylinkedlist.com where your entire job is writing a
               | new linked list implementation every day of the week,
               | Rust might be a bad choice. But that's not what any kind
               | of commercial enterprise actually looks like. If I saw
               | you writing a lockless thread queue at work, I'd tell you
               | to stop wasting time.
        
               | jandrewrogers wrote:
               | > High quality teams like the Linux kernel team and
               | PostgreSQL
               | 
               | Neither of those code bases are C++, which significantly
               | dilutes your point. A major benefit of modern C++ is that
               | it is _much_ safer than the language Linux and PostgreSQL
               | are written in.
        
               | Daishiman wrote:
               | Chromium _is_ written in C++, has some of the best coders
               | and one of the best-tested codebases in the world.
               | They're still finding zero-days based on exploits due to
               | the language's failings.
               | 
               | There's a reason Mozilla has decided that all parser code
               | should be moved to Rust ASAP.
        
               | boris wrote:
               | > There are however valid questions, like if Rust slows
               | down your development say, 5%, would you get more net
               | safety from spending 5% more time testing/fuzzing c++
               | code instead? etc.
               | 
               | I think a similarly valid question is how often you
               | resorted to dynamic allocations just to get the borrow
               | checker off your back. If your Rust version uses 5% more
               | dynamic memory (with the corresponding performance and
               | memory footprint penalty), is it perhaps worth staying
               | with C/C++ and spending more development time on
               | testing/fuzzing?
        
               | smolder wrote:
               | If you're willing to jump back to C++ to get around the
               | borrow checker strictness, couldn't you just use Rust's
               | unsafe block where you're sure it won't result in a bug?
               | 
               | Is it harder to fuzz Rust? Honest question, because
               | fuzzing is something I occasionally read about but am not
               | practiced in.
        
               | duckerude wrote:
               | I've found it very easy to get started with fuzzing in
               | Rust using cargo-fuzz. I didn't do anything very
               | advanced, and my closest point of reference is testing
               | Python with Hypothesis, but it did turn up bugs.
               | 
               | Here's a Rust fuzzing story from yesterday:
               | https://hacks.mozilla.org/2022/06/fuzzing-rust-minidump-
               | for-...
               | 
               | It claims that Rust is particularly suitable for it
               | because integer overflow panics in debug builds (and out
               | of bounds indexing always panics), which sounds
               | reasonable.
        
               | duckerude wrote:
               | Some people make the opposite claim: Rust lets you get
               | away with less dynamic allocation (and more data shared
               | between threads) because you can rely on the compiler
               | checking your work.
               | 
               | The effect might be positive or negative depending on the
               | circumstances.
        
               | jackmott42 wrote:
               | That is a fair thing to wonder about, but at the moment
               | most of the design decisions Rust pushes you toward tend
               | to be better for performance on modern hardware. For
               | instance using an array based arena to store a graph,
               | instead of the traditional allocation of a chunk of
               | memory per node on the heap. Or just keeping more stuff
               | on the stack.
        
             | ostenning wrote:
             | Can you elaborate on the proficiency of your dev team, is
             | this with juniors etc? Is it a large team? And what is the
             | complexity of the project? I think this is important
             | information
        
               | shuger wrote:
               | GPU driver, most devs are senior. Hundreds of thousands
               | of lines of code in the "slice" my team is interested in.
               | Team for our component has on it's own has probably over
               | 40 people.
               | 
               | Driver should be even more prone to programming bugs
               | because most of it is about manipulating data in raw
               | "untyped" memory.
        
               | Daishiman wrote:
               | My experience with GPU drivers then is that your code is
               | likely buggy AF and your team is in denial.
        
               | the_mitsuhiko wrote:
               | GPU drivers are also some of the most buggiest stuff out
               | there I used. When I worked in Games we routinely managed
               | to make the GPU drivers crash which thankfully at the
               | time was already no longer taking down your engine
               | machine.
        
             | bestouff wrote:
             | My manager told me exactly the same thing as you do; after
             | I found a few UB in its code in the first 2 weeks he
             | changed its stance.
        
               | josefx wrote:
               | I had to deal with a senior dev. that gave me a talk
               | about seniority after I ran valgrind over our software.
               | Guy was so deep into the whole senior dev. power trip
               | that he blamed third party libraries for his bugs, dev.
               | tools for "incorrectly" identifying his bugs and wrote
               | more bugs to work around his other bugs.
               | 
               | Finding and fixing issues in C++ code can be easy with
               | the available tools, getting people to use them on the
               | other hand can can be like talking to a wall.
        
               | darthrupert wrote:
               | That sounds more like an expert beginner than senior.
        
               | im3w1l wrote:
               | Sounds like someone who senses his place in the hierarchy
               | is threatened.
        
             | nemothekid wrote:
             | > _The issues that Rust is supposed to help with are simply
             | not what we spent time on._
             | 
             | There could be plenty of bugs in your codebase but just
             | because you don't spend time on them doesn't mean they
             | don't exist. Hundreds of millions of people used OpenSSL
             | everyday for 2 years after the Heartbleed bug was
             | introduced. It didn't cause any obviously broken code until
             | someone exploited it to read credit card numbers off of a
             | remote server.
        
               | [deleted]
        
             | Agingcoder wrote:
             | In practice for you. Where I am, things are very different!
             | Buffer overflows and memory corruptions, threading issues,
             | uninitialized variables, etc appear on a very regular
             | basis, and end up being very difficult to debug, mostly
             | because the moment where you corrupt memory and the moment
             | it triggers a bug can be very far apart.
        
             | strictfp wrote:
             | I've worked in a variety of languages, and returning to a
             | c++ project recently I do see that we spend a lot more time
             | thinking about how to write the code in a way that avoids
             | problems. Meaning that there's a lot more architecturing
             | required to reach a sane state.
             | 
             | We have a sister product written in a dynamic language, and
             | sometimes we have identical functionality.
             | 
             | I've noticed that when a change is discussed, the c++ gang
             | has architectured themselves into the current solution and
             | therefore have a much harder time making changes.
             | 
             | So for that reason I think it's easy to overlook these
             | complexities when you're working in c++ alone; they feel
             | natural and are just part of how you work. You forget that
             | a lot of this architecturing just isn't necessary in a lot
             | of other languages.
        
               | jstimpfle wrote:
               | Maybe I'm wrong, but I believe that most of the
               | architecting that you describe would be effectively what
               | you do with regards to performance as well: Minimizing
               | change of ownership, moving to a system with more static
               | allocations with fewer "objects" that are linked into a
               | variety of subsystems.
        
               | cyber_kinetist wrote:
               | ...and when you do need a large number of dynamically
               | allocced/deallocced objects, then using indices to arrays
               | instead of pointers. Which kinda defeats the purpose of
               | using the Rust borrow checker...
        
               | strictfp wrote:
               | Yes, that's true. In a sense, c++ requires good code
               | structuring.
               | 
               | That's also part of why I enjoy returning to c++, the
               | people involved know how to structure code and create
               | clean architecture.
               | 
               | That said, sometimes c++ does get in the way. Creating
               | trees or graphs can be cumbersome, and IMO it's very
               | biased towards virtual methods to solve polymorphism.
               | 
               | Extending lifetimes by pooling or similar is also quite
               | common, and is in my eyes sometimes overdoing it. If you
               | for instance use Rust, you can be a lot more confident
               | that the compiler catches these issues, and be more
               | conservative and efficient in the solution.
        
               | jhgb wrote:
               | > and IMO it's very biased towards virtual methods to
               | solve polymorphism.
               | 
               | Is it? These days I'd expect C++ to be very biased
               | towards using templates for polymorphism. After all,
               | templates are a thing that C++ provides with
               | functionality that other languages often lack, whereas in
               | the field of virtual methods/"dynamic dispatch OOP" C++
               | severely lags behind other languages. Choosing between
               | two features of a language and using exactly the one that
               | is worse in comparison to your competition feels wrong to
               | me.
        
               | FpUser wrote:
               | I do not think C++ "lags severely in the field of virtual
               | methods". I use both OOP and template based polymorphism
               | depending on particular needs and see no significant
               | problems in either.
        
               | jhgb wrote:
               | C++ can't do things today that Smalltalk and CLOS were
               | able to do in the 1980s already; how is it _not_ lagging
               | behind in OOP? Hell, companies like Trolltech had to
               | extend C++ for their own purposes to provide just a
               | subset of the extra features (relative to standard C++)
               | that had already been available in environments like
               | Smalltalk or CLOS.
        
               | leni536 wrote:
               | Sometimes (definitely not always) you can use
               | std::function instead for dynamic polymorphism.
        
               | jandrewrogers wrote:
               | > very biased towards virtual methods
               | 
               | This is a function of the type of software you write.
               | There are many large C++ code bases that rely on various
               | types of static polymorphism almost exclusively, rarely
               | having a use case for virtual methods or dynamic
               | polymorphism. There is a similar story with inheritance
               | versus composition; some types of code bases naturally
               | gravitate toward one or the other.
               | 
               | The nice thing about C++ is that it as amenable to any of
               | these models should it benefit the application.
        
               | strictfp wrote:
               | I don't agree. The support for static polymorphism is in
               | it's infancy at best.
        
               | jandrewrogers wrote:
               | Can you give some examples of what you mean? I use static
               | polymorphism in C++ routinely and haven't felt
               | particularly limited by it.
        
               | ryl00 wrote:
               | > Creating trees or graphs can be cumbersome
               | 
               | Wouldn't Rust have the same problem with this (if not
               | worse)?
        
               | jhgb wrote:
               | I was told that deferred_ptr/deferred_heap was supposed
               | to solve these things for C++, so perhaps that would make
               | Rust the option with worse problems in this department.
               | Not sure where it got by now, though.
        
             | lmm wrote:
             | > The issues that Rust is supposed to help with are simply
             | not what we spent time on. All the bugs reported are pretty
             | much exclusively root caused to "business logic".
             | 
             | Everyone claims this, probably because business logic bugs
             | are more memorable. But I've never seen it match the real
             | statistics. According to the best published data, null
             | alone is something like 30-70% of bugs, you just don't
             | remember them because they're uninteresting.
        
               | Macha wrote:
               | It depends on the person's mental categorisation of bugs
               | too. For example I could see someone classifying null
               | bugs as business logic bugs because "the business logic
               | didn't account for that information not always being
               | there"
        
               | jhgb wrote:
               | It's a language bug, really. If you're _expected_ to say
               | what the individual things in your program are allowed to
               | be (like you have to in C++, Java, C# etc.), and you say
               | "foo is a BarBaz object", and the language and compiler
               | allow you to set foo to something that isn't actually a
               | BarBaz object and this is considered OK, then the
               | language is botched.
        
               | capitainenemo wrote:
               | I wonder if passing NaN is considered "business logic"
               | Thinking of this interesting exchange long ago by an
               | experienced c++ dev
               | 
               | https://old.reddit.com/r/rust/comments/78bowa/hey_this_is
               | _ky...
        
             | staticassertion wrote:
             | Unsurprisingly the types of bugs reported are going to be
             | around business logic errors and not obscure edge case that
             | users won't run into naturally. The bugs are still there
             | though.
        
               | hgomersall wrote:
               | Right, and if you come across it you can't always
               | reproduce it. "Oh it crashed, yeah it does that
               | sometimes".
        
             | xyzzy123 wrote:
             | I think this mirrors my day to day experience with C++.
             | 
             | On the other hand, fuzzing large c++ programs will
             | routinely uncover memory safety issues in practically any
             | large codebase that hasn't been absolutely beaten to death
             | by fuzzers already.
             | 
             | The issues are not usually so much "I returned this thing
             | on the stack" they tend to be things like "this (very
             | unexpected) sequence of api calls will result in a UAF in
             | this deeply nested data structure over here on the heap".
        
             | mwcampbell wrote:
             | Counterpoint: When I was on the Windows accessibility team
             | at Microsoft, one of my most brilliant colleagues gave a
             | presentation about what to look for when doing code
             | reviews, and he emphasized three main categories: C++, COM
             | (Microsoft's Component Object Model), and concurrency. Rust
             | eliminates many of the issues in the first and third
             | categories. And yes, we were writing modern C++ as much as
             | we could in that legacy codebase; by 2019 we were using
             | several C++17 features, as well as the latest C++ utility
             | libraries for working with COM and WinRT. Given the state
             | of the Rust windows crate, that team (which both I and that
             | colleague left in late 2020) might even be able to use Rust
             | in new code. I'm sure that would make him happy.
        
           | hinkley wrote:
           | The exhausting part for me was always when the bug escapes
           | detection for a little while, is associated with some new
           | functionality that very much did _not_ escape detection, and
           | it turns out that the wrong implementation is faster than
           | possible. Now to fix the bug I get to be the bad guy and take
           | away the customers toys (one of many many reasons to push for
           | making the culprit fix the problem, especially if they don 't
           | want to).
           | 
           | It doesn't take many of these to form a coping mechanism that
           | prevents this from happening again, even if it's at great
           | cost. This is also the genesis of many unwinnable arguments
           | that drag on forever.
        
           | blub wrote:
           | I find neither C++ nor Rust to be particularly "creative"
           | programming languages because one has to think all the time
           | about two things which are irrelevant for the features of the
           | program - resource management and complicated types.
           | 
           | Rust is even worse than C++ because it highly encourages
           | encoding logic in types and the community loves doing that.
           | 
           | You seem to have almost come to the same conclusion yourself,
           | but then mistakenly assume that the same kind of productivity
           | of a GC language is available in a system language. Nope.
           | Although at least in C++ one can just say "fuck it" during
           | the "creative" prototyping phase, copy most things and still
           | have decent syntax and performance. In Rust you'd have to
           | pepper everything with clone, boxes and (a)rc, so you'd have
           | another mess.
        
           | flohofwoe wrote:
           | Static analyzers can catch this stuff nowaways (in this case
           | clang's builtin analyzer):
           | 
           | https://godbolt.org/z/1MfErrYd8
           | 
           | ...in more simple cases it's also a regular warning:
           | 
           | https://godbolt.org/z/5v9YsWd4j
        
           | kevincox wrote:
           | > less time debugging
           | 
           | I would say it isn't even the debugging. As many of the C++
           | programmers here have said as you get good at C++ this
           | becomes something that you are vigilant for and it rarely
           | actually gets written. But just the lack of even needing to
           | think about it is a huge load off my mind. When I used to
           | write C++ I never really realized how vigilant I was. Every
           | time I added code into the middle of a function I had to
           | double check all of the lifetimes, every time I shorted the
           | lifetime of a variable I had to search for it to the end of
           | the function. Just not having to worry about this much really
           | frees your mind for thinking about other things.
        
             | blub wrote:
             | And what are you thinking about now?
             | 
             | For me it was what lifetimes and types to use to make my
             | program work. Just as it was in C++, but with a static
             | verification step at the end which most of the time got in
             | my way.
             | 
             | Rust makes lots of sense in high-churn projects or projects
             | which have very high security requirements (like browsers).
             | Otherwise I'd think carefully about using it.
        
         | fleventynine wrote:
         | Reviewing commits for a security-critical project written in C
         | or C++ can be incredibly tedious. I've spent an entire day
         | trying to validate that the assumptions made by a 10-line
         | change are memory-safe in the context of the larger program.
         | These reviews are incredibly mentally draining, and even when
         | I'm done I'm not 100% sure that I didn't miss something and let
         | a vulnerability into the codebase.
         | 
         | Rust is a breath of fresh air in comparison. Worrying about
         | memory safety isn't even a concern for the vast majority of
         | commits that don't touch modules with unsafe code. All
         | assumptions made about the lifetimes of references are made
         | explicit in the code, and checked by the compiler. On rust
         | projects I find I have much more mental energy to use against
         | other aspects of the problem.
        
         | zh3 wrote:
         | As someone considering learning Rust, the article put me off
         | fast with the long preamble to even explaining what the issue
         | was. I really hope it's not that complicated, but even your
         | rebuttal fills me with fear - "corrupted data [......] being
         | modified by unrelated operations on stack". How would you
         | explain that to put a C programmers mind at ease?
        
       | dj_mc_merlin wrote:
       | If only his webserver were written in Rust.
        
       | FpUser wrote:
       | So many words to describe a simple issue of using reference to
       | out of scope data. Anyways I am using C++ a lot and this types of
       | bugs are easily caught by analyzers or straight up by modern IDEs
       | like CLion (you get a warning).
        
       | z3t4 wrote:
       | A garbage collector has saved my brain from overfrying many
       | times.
        
       | munchler wrote:
       | From the article:                   It's pointing out that we are
       | pushing into this vector         which needs references into "the
       | AST", but we haven't         declared in our signature that the
       | ast::Ty must actually         from "the AST".
       | 
       | I think someone needs to write a typechecker for English to help
       | out the author of this sentence.
        
       | Linda703 wrote:
        
       | labrador wrote:
       | I've used Rust and I like it alright but it has the ugliest
       | syntax of any major language since Perl
        
         | proto_lambda wrote:
         | Have you seen modern C++? It has had new syntax bolted on every
         | couple years for the past few decades, the result is quite
         | phenomenal.
        
           | MauranKilom wrote:
           | Can you name what new syntax you abhor?
           | 
           | I mean, other than []<>(){}() being a valid C++ expression
           | [0], C++ hasn't even made any notable sygil-related syntax
           | changes recently. Sure, some keywords were added (auto,
           | constexpr, co_yield...) but I don't see how that leads to
           | "ugly" syntax.
           | 
           | [0]: That's a lambda capturing no state, having no template
           | parameters, taking no arguments, with an empty body, finally
           | being called immediately with no arguments. But half of that
           | is optional. A more usual lambda would look like [foo](int
           | bar) { return foo+bar; }.
        
             | kingaillas wrote:
             | Anything with templates, type traits, especially when
             | nested. (The kind of spew you get on an compilation error).
             | Even                 template< typename T >       struct
             | foo<T, std::void_t<decltype(++std::declval<T&>() )>>
             | : std::true_type { };
             | 
             | looks terrible and that's just basic.
        
               | masklinn wrote:
               | I still wish Rust had a way to express decltype tho.
               | `impl Trait` doesn't always work, and when it doesn't
               | it's quite frustrating.
        
               | estebank wrote:
               | What limitation do you encounter with `impl Trait`? They
               | might be removed by `type Alias = impl Trait;` soon.
               | 
               | https://rust-
               | lang.github.io/rfcs/2515-type_alias_impl_trait....
        
               | marcosdumay wrote:
               | You will notice that this is almost valid Rust. (Rust is
               | a very small bit better, not enough to matter.)
               | 
               | In fact, a lot of what the Rust syntax ugly was taken
               | from C++, and it took most of what makes C++ ugly. So the
               | entire discussion is just amusing.
        
             | woodruffw wrote:
             | I find the new user-defined literals syntax pretty ugly.
             | Useful, but ugly.
             | 
             | On the older side: the initialization list syntax has
             | always been ugly (and bug-prone, due to the unintuitive
             | evaluation order.)
        
             | mkl wrote:
             | Technically auto was already a keyword (from C) and was
             | just repurposed. Pedantic but interesting.
             | https://en.cppreference.com/w/c/keyword
        
             | ImprobableTruth wrote:
             | 'requires requires' makes me cry
        
           | pclmulqdq wrote:
           | Modern C++ looks horrendously ugly if you are a library
           | writer, but on business logic it looks a lot tamer than rust.
        
         | voidhorse wrote:
         | agreed, I've tried to pick up rust a few times and the syntax
         | has always made me give up halfway through the point of writing
         | a real project. It's really a shame since they had every
         | opportunity _not_ to make the syntax horrible. CPP has
         | horrendous syntax but a lot of that is because they needed to
         | start representing features over time that didn't exist from
         | the ground up. Rust had pretty much all of its killer features
         | form the start but for unknown reasons elected to use a
         | tremendously noisy syntax that seems to be inspired by the
         | monstrosity that is modern cpp syntax.
        
           | kibwen wrote:
           | It shouldn't be surprising that Rust's syntax is inspired by
           | C++, Rust is literally designed to entice C++ programmers,
           | and the syntax reflects that (modulo a handful of
           | irresistible ML-isms to match the type system).
        
         | ajdude wrote:
         | This is my trouble with Rust. Thankfully Ada will do the same
         | things addressed in this article while having a much more
         | readable syntax.
        
       | PointyFluff wrote:
       | If only rust caught blogging security errors.
       | 
       | It's a terrible idea to post a photo of your child with her name
       | on your public blog.
       | 
       | It's one of those subtle security things that the rust compiler
       | helps with; but not here, sadly.
        
       | rob74 wrote:
       | Yes... but before you start feeling too sure about Rust
       | protecting you from creating bugs, also consider this more
       | cautionary (and very entertaining) tale posted on HN today:
       | https://hacks.mozilla.org/2022/06/fuzzing-rust-minidump-for-...
        
         | rq1 wrote:
         | Well you'd have these bugs, plus the memory bugs in other
         | languages.
        
           | fnord123 wrote:
           | They already did. Hence the rewrite from C++ to Rust.
        
         | proto_lambda wrote:
         | You mean the tale of someone rewriting a very complex and
         | fiddly software from scratch, having it work great in
         | production, and then using the ecosystem's great tooling to
         | easily find and eliminate even more bugs than what the language
         | already protected them from?
        
           | kjksf wrote:
           | The thing they rewrote also worked great in production.
           | 
           | And fuzzing originated in C / C++ tools and is available for
           | them as well, probably more diverse and mature than what is
           | available in Rust.
           | 
           | The point you did ignore was: Rust is being sold as magically
           | making software safe and people selling that completely
           | ignore the fact that logical bugs are also a thing.
           | 
           | Which Rust evangelists find difficult to acknowledge because
           | security is that one thing that Rust has going for it.
           | 
           | So difficult that you would rather try to misdirect than to
           | acknowledge that software written in Rust will crash. And
           | when processing arbitrary user output, it'll crash badly when
           | not written with care and fuzzed a lot. Kind of like C++.
        
             | imron wrote:
             | > The thing they rewrote also worked great in production.
             | 
             | It may well have, but the Rust version "was faster, it
             | crashed less, and we even knew it fixed some issues"
             | 
             | https://hacks.mozilla.org/2022/06/everything-is-broken-
             | shipp...
        
             | kelnos wrote:
             | > _Rust is being sold as magically making software safe and
             | people selling that completely ignore the fact that logical
             | bugs are also a thing._
             | 
             | I don't think that's true. Sure, there are zealots who
             | oversell things, but reasonable people (including those who
             | are actual leaders in the Rust community) are realistic
             | about the classes of bugs that Rust eliminates, as well as
             | those Rust doesn't help with.
        
             | sgift wrote:
             | > The point you did ignore was: Rust is being sold as
             | magically making software safe and people selling that
             | completely ignore the fact that logical bugs are also a
             | thing.
             | 
             | There are straw men and then there are straw man armies.
             | This is probably the biggest one I've seen yet.
        
               | sitkack wrote:
               | Ohh, I got one. Rust is _less_ secure than C++ because it
               | causes people to be overconfident in its security
               | properties. The sharp edges of C++ are a feature that
               | cause people to focus on correctness, not just get it for
               | free.
        
               | [deleted]
        
               | Thiez wrote:
               | You jest, but that used to be an argument against making
               | seatbelts mandatory in cars. I suppose people would drive
               | even more safely if there was a sharp metal spike
               | sticking out of the center of the steering wheel.
        
               | kelnos wrote:
               | Hell, this is a _current_ argument some people have
               | against wearing bicycle and motorcycle helmets.
        
               | Thiez wrote:
               | Is it? For bicycle helmets I just know these variants:
               | 
               | 1. Wearing a bicycle helmet is unpleasant, so people will
               | cycle less and possibly use other modes of transportation
               | such as cars. The risk of a traumatic head injury may
               | decrease but this is offset either partially or fully by
               | other health risks such as obesity.
               | 
               | 2. _Other_ road users in heavier vehicles (e.g. cars)
               | perceive riders wearing bicycle helmets as less
               | vulnerable, and so keep less distance when overtaking
               | them, thus wearing a helmet increases the risk of
               | collision.
               | 
               | I don't think I've ever heard someone say they won't wear
               | a bicycle helmet because it would make them personally
               | drive more dangerously.
               | 
               | I personally strongly oppose mandatory bike helmets. I
               | think one of the reasons so many people own and ride
               | bikes in my country (The Netherlands) is that we don't
               | have mandatory helmets. Making helmets mandatory for
               | people inside cars would also prevent or reduce head
               | injuries (and indeed that is why they are worn by race
               | car drivers) so if we ever introduce mandatory bicycle
               | helmets here perhaps we can introduce mandatory car
               | helmets at the same time, to ensure that people won't
               | just take a car instead.
        
               | sitkack wrote:
               | This assumes that each person is responsible for their
               | own safety. But you have no control over the other guy
               | that puts people at risk. By mocking it, maybe we can
               | prevent this form of argumentation earlier?
               | 
               | Hopefully in 20 years or less we will see unsafe code in
               | the same way we view leaded gas, cigarettes and CO2. The
               | other thing I realized in the last couple years is that
               | eventually, everything becomes safety critical to someone
               | at some point. That if you think you have to _just_
               | protect this one system but that others can fail, is
               | flawed on large scales. You can 't tractably realize the
               | failure graph, and nor can you prevent a seemingly
               | innocuous thing from being used in a critical way.
               | 
               | The pandemic was a great lens into how human resilience
               | kept flawed systems functioning in a way that few
               | realized were flawed. The pharmacies in my area are still
               | recovering only to have their problem exacerbated by more
               | rigid controls that prevent local autonomy from making
               | the system resilient. In this particular case, automation
               | has made a problem worse by preventing humans from doing
               | the little local silent repairs that they were previously
               | doing.
        
               | carrionpigeon wrote:
               | The great (unintentional?) irony of that argument is that
               | before seatbelts, that was arguably how cars used to be
               | manufactured. Back then, drivers were often killed in car
               | crashes by being impaled on the steering wheel. Those in
               | the passenger seat would die from being hurled through
               | the window. Despite the elevated risk in those older
               | cars, drivers weren't safer --- they were unsafe to such
               | a degree that it formed the argument for mandating seat
               | belts in the first place.
        
             | proto_lambda wrote:
             | > The thing they rewrote also worked great in production.
             | 
             | It didn't for them, that's why they rewrote it.
             | 
             | > Rust is being sold as magically making software safe and
             | people selling that completely ignore the fact that logical
             | bugs are also a thing.
             | 
             | By whom? I don't think memory safety bugs are the only
             | class of bugs, and neither do you, so who are you arguing
             | against?
             | 
             | > Which Rust evangelists find difficult to acknowledge
             | because security is that one thing that Rust has going for
             | it.
             | 
             | Hard disagree. Rust also offers a solid type system, pain-
             | free dependency management and all-around good tooling,
             | just to name a few. It's much more than a "memory-safe C++"
             | or whatever.
             | 
             | > And when processing arbitrary user output, it'll crash
             | badly
             | 
             | If your definition of "badly" is "at a well-defined point,
             | without any memory corruption", sure. But even here memory
             | safety prevents what could be a much more painful debugging
             | experience.
        
             | ordu wrote:
             | _> The point you did ignore was: Rust is being sold as
             | magically making software safe and people selling that
             | completely ignore the fact that logical bugs are also a
             | thing._
             | 
             | You know, I'm a Rust evangelist. And I can tell you, why I
             | ignore logic bugs when trying to sell Rust. Rust can
             | prevent some logic bugs if they break invariant you managed
             | to encode or enforce in your types. But it is a difficult
             | topic to dive in a internet discussion. The best I could do
             | is to bring some anecdotal data points, like &str being
             | guaranteed to contain only valid utf8 strings. The worse
             | issue (for a discussion) that it may be not obvious what
             | kind of a logic error can be fixed by the type invariant
             | discussed. So to show it I need to find some more examples
             | of bugs that were prevented by enforcing the invariant. But
             | you see, bugs that were prevented were not documented. It
             | goes like this: you write code, it doesn't compile because
             | rustc is unhappy, you fix code and it compiles nice now,
             | you call it a day and move along. When you fixed this small
             | issue it was not a bug, just one of a several complaints of
             | rustc. You would need to speculate a lot about what could
             | happen bad if rust allowed this issue to live.
             | 
             | We can try to get to the point from a different angle and
             | to find logic errors in a wild, and then to speculate how
             | type invariants might prevented them _if programmers had
             | written their types in a some particular way_. But it raise
             | a question: would they write their types in this way before
             | they faced this particular logic error?
             | 
             | If I tried to talk about complex relationships of Rust and
             | logic errors, I would need to dive into an ocean of
             | speculations. Rust deniers are not very cooperative on this
             | regard, and I'd bet they would just dismiss all the
             | speculations as... well... speculations. And they would
             | keep insist that if we cannot measure a falling frequency
             | of logic bugs, then it is all immaterial. Some even go
             | further and claim that if some tool doesn't prevent _all_
             | bugs of a kind, then it is a useless thing.
             | 
             | So it is not a fun to talk about logic errors with rust
             | deniers. Among rust evangelists the talk doesn't happen
             | either, because they do not split bugs into two categories
             | "logic" and "memory" bugs, they split them into "can be
             | prevented by type invariant" and "cannot be prevented by
             | type invariant, or too f*king difficult to". They talk
             | about memory safety to laymen because it is something that
             | laymen understand and it doesn't need explaining. And Rust
             | can prevent all the bugs of this kind, so even when we talk
             | to a people who thinks in black-and-white, we can make
             | statements that are defensible in this Aristotelian
             | tradition of excluded middle.
        
               | sitkack wrote:
               | You often encounter this entire thread of rhetoric when
               | someone wants to put a diversion into the central
               | argument, yeah but it doesn't ____.
               | 
               | But Rust _does_ do that, match exhaustiveness, forcing
               | the handling of errors and the type system enables things
               | like CreuSAT [1] using creusot [2]
               | 
               | [1] https://news.ycombinator.com/item?id=31780128
               | 
               | [2] https://github.com/xldenis/creusot
               | 
               | > Creusot works by translating Rust code to WhyML, the
               | verification and specification language of Why3. Users
               | can then leverage the full power of Why3 to
               | (semi)-automatically discharge the verification
               | conditions!
               | 
               | Units of Measure, https://github.com/iliekturtles/uom
               | 
               | The base properties of the language enable things that
               | can _never_ be done in C++.
        
               | scatters wrote:
               | You mean like Boost.Units?
        
               | sitkack wrote:
               | Great example of the kind of cherry picking in these
               | conversations. It is insincere and uncharitable, all you
               | did was show your colors. Didn't say everything was
               | exclusive to Rust, while you make no mention on the
               | ground breaking work in CreuSAT. Given as an example of
               | the kinds of things besides memory lifetime tracking that
               | can make Rust code more robust against logical errors.
        
             | rob74 wrote:
             | What you said, although I would have probably phrased it
             | less harshly :)
             | 
             | But yes, my point was that there are a lot of enthusiastic
             | articles about how Rust can prevent "whole classes of
             | bugs", which mostly gloss over the fact that there are
             | other classes of bugs that it doesn't prevent. Of course
             | this doesn't mislead experienced developers, but I'm not so
             | sure about novices or less technically inclined people.
        
               | nindalf wrote:
               | It seems like it is true and accurate to say that Rust
               | prevents "whole classes of bugs". It is obvious that
               | other bugs can still exist. Otherwise people would say
               | Rust prevents "all bugs".
               | 
               | Are you disappointed that Rust evangelists don't spend
               | time talking about the fact that bugs can exist in Rust
               | programs? Did you see the two articles posted in the last
               | week alone about bugs that were found in Rust code? They
               | reached the front page of HN
               | 
               | - https://hacks.mozilla.org/2022/06/everything-is-broken-
               | shipp...
               | 
               | - https://hacks.mozilla.org/2022/06/fuzzing-rust-
               | minidump-for-...
               | 
               | If you want to see criticism of Rust, I've found that the
               | most informed criticism comes from people who use Rust a
               | lot. Example - https://matklad.github.io/2020/09/20/why-
               | not-rust.html
        
               | tremon wrote:
               | _which mostly gloss over the fact that there are other
               | classes of bugs that it doesn 't prevent_
               | 
               | That's nothing more than a technically-dressed version of
               | whataboutism, isn't it? Or can you show other languages
               | that _do_ prevent those other unnamed classes of bugs?
        
               | rob74 wrote:
               | Er... no. I was simply saying that the many articles
               | about how reliable Rust is and how many bugs it catches
               | for you might lead to a false sense of safety. Nothing
               | more, nothing less.
        
               | supportlocal4h wrote:
               | What's the use of standing on that anti-static mat and
               | wearing that grounding strap? Can't you see there are
               | fork lifts zipping around just right in the next room?
               | That mat is giving you a false sense of security!
        
         | carnitine wrote:
         | This seems like the opposite of a cautionary tale, if anything
         | it makes Rust seem an even better choice.
        
         | ekidd wrote:
         | I have run "cargo fuzz" (based on the AFL fuzzer) over a
         | binary-format parsing library I wrote, generating roughly a
         | billion inputs. Here's what I learned:
         | 
         | 1. Rust does not protect you at _compile time_ against  "index
         | out of bounds" errors. If you want that, you'll want a
         | dependently-typed language like Idris. Which still wouldn't
         | help much in this case.
         | 
         | 2. However, Rust catches index errors perfectly well at
         | _runtime,_ and performs a controlled panic. This does not
         | result in a privilege escalation, but it may cause a denial of
         | service. So fuzzing in (safe) Rust is normally a  "lower
         | stakes" activity.
         | 
         | 3. "cargo fuzz" is super easy to use, and AFL is pretty
         | amazing.
         | 
         | 4. If you think you can parse complex, badly-documented low-
         | level binary formats without ever having an index error, you're
         | probably wildly overconfident. In the case of the minidump
         | parser, it's worse: The data was generated by a crashing
         | process, and in many cases, the data _caused_ the crash.
         | 
         | Let's look at what the author concludes:
         | 
         | > _And what did we screw up? Some legit stuff! It's Rust code,
         | so I am fairly confident none of the issues were security
         | concerns, but they were definitely quality of implementation
         | issues, and could have been used to at very least denial-of-
         | service the minidump processor._
         | 
         | A whole bunch of issues, probably none of them leading to
         | security escalations. And unlike many C fuzzing experiences, it
         | was largely painless:
         | 
         | > _By comparison I am absolutely thriving under "Yeah you can
         | deterministically trip this assertion with this tiny input you
         | can just check in as a unit test"._
         | 
         | This happens because Rust catches most of these errors very
         | early, using assertions in the standard library. So your fuzz
         | reports often need to be tracked for only a few lines.
         | 
         | TL;Dr: Parsing complex binary formats usually involves subtle
         | bugs. Rust does not promise to catch index-out-of-bounds at
         | compile-time, but it catches them at runtime. This makes
         | fuzzing easy and productive.
         | 
         | Overall, I'd call this a success story. The author underwent an
         | inevitably humbling experience for low stakes under controlled
         | conditions. And now the library can parse corrupted examples of
         | an incredibly nasty format, with high confidence that the worst
         | thing that will happen is a runtime error (not even a DoS).
        
         | hnarn wrote:
         | > I needed a bit of palette cleanser
         | 
         | This is a fun mistake. It's "Palate cleanser".
        
           | rob74 wrote:
           | Works with palette (as in painter's palette) too - start with
           | a clean slate, use a whole different set of colors etc.
        
           | gpderetta wrote:
           | Maybe they just want to drink solvent. A common reaction
           | after dealing with very bad code for a while.
        
       | inox wrote:
       | I was looking for some kind of story related to cooking bacon
       | with Rust -> disappointed. Bacon is only used once - in the
       | heading...
        
         | proto_lambda wrote:
         | It's an idiom:
         | https://en.wiktionary.org/wiki/save_someone%27s_bacon
        
         | antegamisou wrote:
         | Similarly expected a firmware write-up for an IoT BBQ.
        
       | axilmar wrote:
       | Rust is undoubtedly a step forward in correctness, but boy, the
       | article's code is so thick that for me, that I am a C++
       | programmer, is almost unreadable, especially for a quick
       | reading...
       | 
       | I skipped all the code and only read the text. I got to the point
       | where it mentions that the language prevented them from storing a
       | pointer to a stack object in a heap object, and that's really
       | great, but boy oh boy, the code presented, and the error
       | messages, where very difficult for me to grok even after the
       | first few times...
       | 
       | It seems to me that the more sophisticated the safety a language
       | provides is the more complex its error messages/code are. It
       | would be so nice if we could solve both problems at the same
       | time...
        
         | dijit wrote:
         | For whatever it's worth: I think it's harder to learn rust as a
         | C++ programmer than it is for a new programmer.
         | 
         | Reason being that you have to unlearn your paradigm before
         | you're able to learn the new paradigm; and it's made slightly
         | worse by giving the appearance of similarity (since certain
         | concepts map directly, like flow control and loops).
        
           | proto_lambda wrote:
           | One big hurdle for C++ programmers learning Rust that I've
           | seen time and time again in various community support
           | channels is fixing their trust issues with the compiler. They
           | are so used to compiler output being useless or worse than
           | useless, they are unable to take advantage of rustc's stellar
           | diagnostics (which frequently tell you exactly what you need
           | to change to make things work) until they force themselves to
           | actually read and internalise them.
           | 
           | Once they realize that the tooling is actually working _with_
           | them, not _against_ them, they start to pick things up much
           | quicker.
        
             | lionkor wrote:
             | In my experience only beginners have this issue, as a C++
             | programmer the compiler is my best friend.
        
             | scoutt wrote:
             | > big hurdle
             | 
             | Without going much further, to me it's the syntax. I can
             | write some Rust lines of code, and I appreciate the
             | compiler output to correct my syntax. But it's really
             | difficult to me to read code written by others. I can't
             | open a random file of a Rust project and have a minimal
             | clue of what's going on
             | 
             | After years of C and some C++, I have a parser implanted in
             | my cerebellum, and it's hard to adapt it to Rust. To me,
             | reading Rust feels like forcing an optical nerve to see
             | something very small.
             | 
             | Case in point, the code in this article.
        
               | bilkow wrote:
               | Oh yeah, I feel your pain, my brain is really used to
               | Rust/Swift and Python syntax, and when I have to read
               | Typescript/React, C++ or something like Nix, it gets hard
               | for my brain to parse it. Loved the eyesight analogy!
        
         | lawn wrote:
         | As a Rust programmer I think the code could have been made much
         | simpler and still get the point across.
         | 
         | I think the author wanted to replicate the code as closely as
         | possible, so it's more a case study than an educational piece
         | if that makes sense?
        
         | dgb23 wrote:
         | I skimmed the code and there are a ton of language features in
         | there that you might not be super familiar with:
         | 
         | - pattern matching is quite expressive and ubiquitous in Rust,
         | as in "stuff on the left" is almost always a pattern even in
         | places that you might not expect at first
         | 
         | - lifetime annotations, a form of generics, are quite unique
         | and make the code more verbose/noisy if you are not familiar
         | with them
         | 
         | - Rust is expression based (a bit lispy) so you might not quite
         | see the flow of the program as well if you are used to
         | statement based syntax
         | 
         | - traits are are an important part of the language and some of
         | the methods and method chains you see there might look
         | arbitrary, but many of them are very common. A more experienced
         | reader can identify many of them and see the code very
         | differently.
         | 
         | - there is no syntax highlighting on the article's snippets so
         | you already have to know how to parse them
        
         | azakai wrote:
         | > It seems to me that the more sophisticated the safety a
         | language provides is the more complex its error messages/code
         | are. It would be so nice if we could solve both problems at the
         | same time...
         | 
         | That is incredibly hard, yes. But at least if you are ok with
         | the overhead of GC or RC then this is a solved problem - the
         | bug in question here wouldn't happen in
         | Go/Swift/C#/Java/JavaScript/Python/Ruby/etc. And that is most
         | software today.
         | 
         | (But when you need maximal performance and maximal safety then
         | Rust is an incredible option!)
        
         | OneWingedShark wrote:
         | Look at Ada and its error-messages.
        
         | blub wrote:
         | After reading a good chunk of the Programming Rust book (minus
         | concurrency, async and macros) I can understand that. My C++
         | experience helped a lot in comprehending and mentally mapping
         | Rust concepts.
         | 
         | As far as I can tell, that's normal Rust code, but yes it's
         | unreadable if you come from C++ or another language and don't
         | know Rust syntax. The funny thing is that this kind of code is
         | supposed to be the readable part of Rust :-)
        
       ___________________________________________________________________
       (page generated 2022-06-24 23:03 UTC)