Need help?
<- Back

Comments (124)

  • himata4113
    My biggest problem with the refusal to be memory safe is the fact that those problems end up becoming my problems when I am forced to use these applications and I have to think about how there might be a zero-click zero-day that uses an overflow in some random codec. Not as a software developer, but a regular person I want my application to be written in rust or at least use fil-c at bare minimum.Now as a software developer I feel like this is even more important because I use libraries maintained by thousands of other developers that might also use applications that have these exploits which get their systems compromised pushing malware to thousands of other developers which end up compromising even more libraries.I believe that memory safety should be the standard for software that thousands if not millions rely on and that it shouldn't be some political issue of X is better, Y is that, Z is something else.But then again, social engineering is the primary source of malware spread so I don't know.
  • smj-edison
    This is perhaps a different take, but one reason I love Zig and C is because I've learned how to reason in pointers. I've worked with Rust in the past on a ~12,000 LOC side project, so I was all in with tree ownership and XOR mutability. But it turns out there's all sorts of delightful data structures that you can only express with unsafe in Rust. Intrusive doubly linked lists are the coolest thing ever. The fact that I can have a LRU cache that changes what's at the front by shuffling some pointers, while still keeping stable addresses so the hash map stays stable? That's freaking cool. Atomic operations with pointers for linked lists is really slick for implementing an allocator's free list between threads. Being able to walk a live heap using a breadth first search by just... following pointers, made the elegance of Dijkstra's algorithm come alive.Now, maybe I'm only running into these algorithms because these are the problems I'm running into, but in the Rust community I consistently got the message that linked lists were a legacy data structure. In some cases they are, but when they do apply they do so brilliantly.I know working in Zig leaves plenty of room for memory unsafety. Perhaps that's a bad thing. But I'm implementing an interpreter, and these algorithms are essential for it to run fast. I really do need to be aware of where every allocation happens, and what instructions the computer is running. So for now I stick with Zig, even though I know I'm opening myself up to memory exploits.
  • inigyou
    I think the "Fil-C is safer than Rust" thing is an understandable reaction to 10 years of Rust evangelists telling people they have to use Rust otherwise they're stupid and wrong.
  • bubblebeard
    This made me think and reflect, thank you.Not so much about language design as how easy it is to take a defensive position on something we are comfortable with when it's challanged. This prohibits growth.When someone suggests you have been doing something the wrong way or has a new idea, it's usually better to hear them out and take what knowledge you can from them, even if they weren't actually trying to help you.Anyways, thanks again
  • nanolith
    Personally, I see these language fights as being a bit pointless. They are trying to optimize at the wrong layer. Unless one is working with a dependently typed language, which requires a proof assistant to discharge type checks, then it's all just a question of where you make the trade-off. Don't care about memory leaks or deadlocks as part of your soundness guarantees, but can't have GC? Use Rust. Okay with runtime overhead to verify checks? Consider fil extensions.If you want to go deeper, skip the language wars entirely. Tooling does what these languages can't do. I have had great success model checking C with CBMC. Not only does this prevent memory safety issues (including memory leaks), but this also prevents deadlocks. Bonus: you can write user contracts and invariants to verify that every execution path of a function fulfills these contracts and invariants.Kani comes close with Rust. It doesn't yet have decent concurrency support, but there is nothing that prevents this from being added in the future. The ability to write custom contracts and enforce custom invariants more than makes up for its lack of concurrency support. Similar technology could be used or adapted for Zig or C++.Use whichever language you like. Just, please look into model checking it. The technology scales just fine, once you get over the learning curve and learn how to use compositional verification.
  • Animats
    Trying to figure out Fil-C's "inviscaps".[1]When you allocate space with Fil-C's "malloc", some additional bounds checking data precedes the space the program gets to use. Pointers are "fat pointers", with a pointer to the beginning of the buffer and a pointer to someplace within the buffer, allowing ordinary C pointer manipulation.There's much new verbiage around this. But it's roughly the same idea as GCC "fat pointers".[2][3] So it's not a new idea. It's one that's been tried several times, but never caught on.There's a performance penalty. Especially if the compiler can't hoist the checks out of loops.[1] https://fil-c.org/invisicaps[2] https://williambader.com/bounds/example.html[3] https://www.doc.ic.ac.uk/~awl03/projects/miro/MIRO.pdf
  • throwlifeaway
    Pizlo is not a memory safety absolutist. His rhetoric towards rust is a tactic specifically designed to draw more attention to him and his project. It is amplified by people who already had a bone to pick with rust and take joy in giving rust folk "a taste of their own medicine," so to speak. Articles like this are taking the bait.
  • inigyou
    I don't think you need to be an absolutist or only use memory safe languages but it's very obvious that we need to do a whole lot better than we actually do. Rewriting in Rust or any other language is one way to do that, but not a perfect one. I'll accept C++ when most C++ software has 1 in 50 chance of an RCE and not just a 1 in 50 chance of a known RCE. I think we can get there but we are not currently there.Coreutils has a good track record. Ffmpeg doesn't. They should have rewritten ffmpeg in Rust, not coreutils.There are other approaches though like formal verification.
  • Mordak
    The article points out what I think is the crux of the discussion: With Fil-C they become crashes. Errors manifest at runtime, not at compile time.I realized some time ago when I talk to people about rust, I don't really mention memory / thread safety in a security context, I mention them in a reliability context. Compile-time checks mean I basically never spend time debugging runtime crashes, and generally can count on the compiler to catch memory and thread safety issues before the program ever runs, and this saves me time and aggravation in production. I care about security, but I care more about reliability, and rust compile-time checks mean my software is reliable in a way that runtime-checked languages just aren't.This applies to lots of languages. Every time I hit a runtime crash in python, or ruby, or js I die a little inside. Even though they are memory-safe because they're garbage collected, I still waste time debugging runtime errors.
  • robalni
    I don't know if there can be any memory safe languages. Programming is always unsafe because you can always make mistakes. The best we can do is to use tools that help us avoid the common mistakes.As an example of that, the rust compiler helps the programmer to avoid many mistakes but it's still possible to use memory incorrectly and the tool is only safe as long as you use it as intended. You could say that C is safe too as long as you use it as intended and make no mistakes. The only problem is that it's hard to use it as intended and make no mistakes.So let's think about what memory safety could mean. My understanding is that a memory bug is when you use memory in an unintended way. An example of that is when you write to memory after you have deallocated it, which means after you have decided not to use it any more.No compiler or tool can make sure you don't write to or read deallocated memory, because whether it's allocated depends on what your intention is, and no compiler can read your thoughts. They can only give you a tool (like functions for allocating and deallocating memory or compiler checks) and hope that you will use that tool in a way that reflects your intention. One problem is that those tools are not always sufficient to keep track of your intentions and you may not always use them as intended.Memory allocation is relative. In a sense, no program that runs under an operating system can use deallocated memory, because when they read or write to memory that has not been mapped to the process, they crash. In a sense, even "safe" rust can use deallocated memory; let's say you have an array of 10 integers and you decide that the fifth integer should not currently be used, you have then deallocated it on a level where the available tools can not help you, but you can of course still access that memory.So again, everything is safe if you use it as intended and nothing is safe if you use it in other ways. Safety depends on how well the code matches your intentions. Remember that programming always happens in layers and no tool can cover all of them. It's not even clear what "all layers" would mean or how many there are in a program.
  • noelwelsh
    Good article. Not much to add to it, other than I think more people should look at modal type systems like found in Scala 3 and OxCaml. If you want safe arena allocation they are a lot more ergonomic than Rust's approach.
  • leni536
    Fil-C is basically an alternate ABI and libc runtime. Otherwise it is not tied to C and I see no reason it couldn't be targeted by Rust or Zig.
  • pizlonator
    The problem with this post is the extent to which it shows that its author has an unhealthy obsession with me personally. It’s weird but also oddly flattering.I don’t dislike Rust, and when I point out that Rust is not fully memory safe, it’s because I find the details here super interesting. It’s interesting that Rust deliberately chooses to have an unsafe subset. It’s interesting how that leaks out to the rest of the language. It’s interesting because us language designers ought to be thinking about how this could be avoided. It’s a hard problem! And that makes it fun!If you do read what I say on twitter, you’ll find praise for Rust, many concessions about Rust being faster than Fil-C, as well as a wide range of other opinions. When I point out Rust’s unsafety, I’m just citing facts. It’s interesting how doing that really seems to upset some folks.Pointing out a limitation in a technology does not imply dislike, and it’s best not to take it personally.
  • tptacek
    Once again, people are grappling with an axiomatic definition of "memory safety" and avoiding the fact that it's a term of art with a very specific meaning: comprehensive protection from The Memory Corruption Vulnerabilities, which include overflows, the lifecycle vulnerabilities like UAF and type confusion, and uninitialized variables.To the extent Fil-C and Rust both address these vulnerabilities, and don't include design features that in any practical way admit them, they're memory safe. What always feels like is missing from these kinds of analyses is that there are lots of memory-safe programming environments. Almost every Java, Python, Ruby, Javascript, and Go program is memory safe, in the real meaning of the term.The competition to lock in and promote adoption of the "most" memory-safe language is a category error... unless you do what every language-war argument does, and redefine the term.
  • anon
    undefined
  • kmeisthax
    I was not aware of the antagonism from the Zig / Fil-C people to Rust, but it makes absolutely no sense.Like, of course you can prevent all memory safety errors by using a garbage collector. That has been known since the 90s. In fact, there was a good two decades after Java released where all the research on memory safety just stopped, because the standard answer became "use a GC". If you couldn't use GC, you were stuck with languages made prior to Java - which in practice meant just C - or the one language everyone tried to staple every new programming paradigm onto, C++.In fact, part of why C++ became such an untameable beast of a language is because it became load-bearing for non-GC projects. Anything not in the ISO C++ standard was, in practice, something you just couldn't do in native code. Oh, of course you can't introspect structs in a compiled language, of course macros are useless and unhygenic, of course templates have to be monomorphized and bloat your binary size. And so the pressure for C++ to be an all-singing, all-dancing, all-dressed language grew.Rust's big story is memory safety, but the more Rust I wrote, the more I realized that the memory safety is only part of the picture. Rust has a very nicely curated selection of features that allows the language to remain understandable despite the sophistication of the compiler. Memory safety is a selling point, sure, but it is also the lubricant that makes working with those features pleasant.If you want a real complaint about Rust, it's that some features are oversimplified in ways that make certain scenarios harder and make some features way more "magic" than they should be. Have you ever tried writing Futures code without making use of the async keyword? It's nearly impossible, for several reasons; the main being that Rust's type systems cannot express self-referential borrows. This also makes returning a reference to something in an Rc or RefCell you own more difficult[0]. And there are numerous other states memory can be in that are hidden from Rust's type system. Rust can't even represent a real destructor fn. Dropping a value multiple times, or using it after it's been dropped, is explicitly forbidden; but Drop impls still can't take values out of themselves because Rust doesn't have an "owned reference" - i.e. memory you can take values from but can't deallocate.But none of this compromises memory safety - it just makes certain things harder than they should be.[0] Strictly speaking, there's an owning_ref crate that manages this; stdlib is also working on a "mapped mutex guard" type that would do the same thing without a dependency.
  • userbinator
    As long as the corporates continue to erode personal freedom with their hostilities, I consider these "memory safety absolutists" authoritarians, because humans will always make mistakes one way or another, and that should be the natural state of things, as attempts to banish all human error under some guise of "safety" will eventually lead to a horrible dystopia."Freedom is not worth having if it does not include the freedom to make mistakes.""They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety."
  • Panzerschrek
    The main problem of Fil-C or similar solutions is not that they provide absolute safety with no escape hatch (unlike languages with unsafe keyword). The problem is that they provide an excuse to keep using terrible programming languages like C and C++ allowing memory safety issues in the first place.
  • blurgrin
    > Our historical data for C and C++ shows a density of closer to 1,000 memory safety vulnerabilities per MLOC.Unfortunately, I've never seen a version of this data targeting modern C++ (>=11, with smart pointers, already 15 years old).
  • bloaf
    As long as rowhammer is still out there, aint none of your memory safe. Fixing rowhammer is the memory safety absolutism I want to hear more about.
  • rowanG077
    Something that is important to me is that it's caught at compile time. A memory issue is a logic bug. Fil-c simply moves that from undefined behavior/security issue/incorrectness to a crash. That's better than what it was. But I generally don't want my programs to crash. Having memory safety at compile time is much more worthwhile imo.
  • Shorel
    How is this better than the GC in D?
  • hmry
    It's annoying how many comment sections online are now just Rust vs Fil-C / Zig flamewars, and the creators of those languages are deliberately fanning the flames.I also feel there's a second dimension to the politics, where Rust is the "woke" language and C / Zig / Odin are now the "anti-woke" languages. At least, going by their most vocal online communities.I'm sure offline there's still engineering decisions being made (I hope).
  • quotemstr
    > And I also think it is totally fine to use Rust even if you could use a GC language like Go or Fil-C.The problem with choosing Rust over a GC language like the above (or a good one, like OCaml) isn't that it's not "fine" to use Rust, but that manual memory management is an inefficient use of developer time. That's an issue for the developer, and one he inflicts on himself, not an issue for the end-user. Both Rust and (safe) GC languages provide memory safety, after all.
  • IshKebab
    Repeat after me: Rust is not just memory safe C++!Memory safety is a really big reason to use Rust, but it is very very far from the only reason. Even if Fil-C was magically zero-overhead (that is basically what CHERI is), I would still rather use Rust.Rust has so many advantages over something like Fil-C it's hard to list them. I think Fil-C is a great project but it's only really relevant if you have no choice but to use C. If you can use Rust you also get:* Compile time memory safety (Fil-C / CHERI are run-time).* A modern functional-style type system (helps prevent logic bugs).* Tree ownership (helps prevent logic bugs)* Sane toolchain (helps prevent hair loss).* Easy dependencies.* Vastly more things checked at compile time.Also I find it amusing how this post claimed it wasn't about Rust and then spent the whole time talking about it.Rust is great. I don't think that really needs to be debated any more.
  • enbugger
    Funny to see how Rust devs start to make up new labels when it turns out some language performs better then their language.
  • hkalbasi
    Someone should fire up an AI and create Fil-Rust by connecting the Fil-C llvm backend to rustc, ending this flamewar. I guess it is well within the capabilities of a Fable class model, even if the driver doesn't have experience in compiler development.
  • yjftsjthsd-h
    > But Rust is unsafe, isn't it? It has unsafe after all! If you want to be that strict, or in other words, if you are a memory safety absolutist, that may well be true for you. I, and I hope most people, am more pragmatic than that.So... Yes, Rust is less safe. Just that now the Rust apologist wants to back away from that and say that actually memory safety isn't actually the end all be all. C has a lot of security problems. Rust has less, at the cost of breaking the ecosystem. Fil-C has even less, and breaks the ecosystem. Why is the place Rust stops now suddenly good enough?
  • dadrian
    There are only three programs where memory safety matters: HTTP server, browsers, and operating systems. In practice, really just browsers and operating systems. Memory safety schemes that don't work for those systems are primarily cosplaying if their goal is safety.