HN Debrief

Memory Safety Absolutists

  • Programming
  • Security
  • Developer Tools
  • Open Source

The post pushes back on "memory safety absolutism" by arguing that Rust is not the only serious route to safer systems software. It highlights Fil-C, a project that adds runtime-enforced memory safety to C through a custom runtime and ABI, as evidence that you can get strong protections without rewriting everything into Rust. That matters because a lot of deployed software is still C or C++, and replacing it wholesale is slow, expensive, and often unrealistic.

If you ship software in C or C++, the practical question is not "Rust or nothing" but which safety layer you can adopt now without blowing up performance or integration. Treat runtime-checked C, safer languages, and formal verification as complementary tools, then choose based on where crashes, rewrites, and compatibility actually hurt your business.

Discussion mood

Mostly pro-memory-safety and mildly pro-Rust, with impatience toward culture-war framing. People liked the idea of making old C code safer, but saw the post as overstretching Fil-C into an argument against Rust rather than a complement to it.

Key insights

  1. 01

    Fil-C revives old fat-pointer ideas

    Fil-C's invisicaps approach looks less like a new breakthrough and more like another pass at fat pointers plus bounds metadata. That reframes the project from "new category" to "known technique with known trade-offs," especially compiler difficulty around hoisting checks out of loops and the resulting performance hit.

    Evaluate Fil-C like a hardened runtime, not like a free safety upgrade. Before betting on it, test hot loops and pointer-heavy code paths where repeated checks can wreck throughput.

      Attribution:
    • Animats #1
  2. 02

    Model checking reaches beyond language safety

    Tools like CBMC for C and Kani for Rust attack a different class of problems than language design does. They can prove memory safety, deadlock freedom, and custom invariants over execution paths, including cases where a safe language still cannot express or enforce the property you care about.

    If you run high-risk infrastructure or embedded code, add verification tooling to the conversation early. A proof of key invariants can be worth more than a language migration plan that still leaves concurrency and logic bugs untouched.

      Attribution:
    • nanolith #1
  3. 03

    GC, Rust, and Fil-C cover different failure modes

    Garbage collection does not solve the full memory-safety problem. It helps with use-after-free and invalid lifetime issues, but not out-of-bounds access on valid allocations. Rust, runtime-checked systems like Fil-C, and garbage-collected languages each fence off different parts of the problem space. Treating them as interchangeable hides where bugs will still get through.

    Map the actual bug classes hurting your systems before choosing a platform strategy. If overflows dominate, a move from manual memory management to GC alone will not buy what you think it will.

      Attribution:
    • kmeisthax #1
    • estebank #1
    • davidgay #1
    • saghm #1
    • zbentley #1
  4. 04

    Compile-time guarantees and runtime checks are not rivals

    Catching errors at compile time prevents buggy builds from shipping, while runtime checks contain damage when static analysis cannot prove safety. Even Rust mixes the two, since bounds safety often depends on runtime checks that optimizers try to hoist away from inner loops. The useful distinction is not ideology but whether the remaining checks are acceptable in production.

    Ask two separate questions in architecture reviews. First, what failures can we rule out before release. Second, what checks remain on the hot path and what happens when they fire in production.

      Attribution:
    • rowanG077 #1
    • muvlon #1
    • Animats #1
    • wat10000 #1
  5. 05

    Fil-C adoption is really an ABI question

    Fil-C was described less as a language and more as an alternate ABI and libc runtime that currently takes C as input. That is why "just use Fil-C" is not a small swap. It can break interoperability assumptions across existing toolchains, libraries, and deployment environments even if the source language stays the same.

    Treat any Fil-C pilot like a platform migration, not a compiler flag flip. Inventory FFI, dynamic linking, and packaging constraints before assuming legacy code can move over cheaply.

      Attribution:
    • leni536 #1
    • yjftsjthsd-h #1
    • afdbcreid #1
  6. 06

    Unsafe Rust is still a tax on low-level data structures

    People doing allocators, interpreters, intrusive lists, and pointer-stable caches said Rust can express these designs, but often only by pushing into unsafe code and awkward pointer machinery like `addr_of_mut!`. That does not invalidate Rust's safety story. It does show that some low-level algorithms become harder to write and reason about, even when crates like cordyceps help.

    If your team lives in allocators, schedulers, VMs, or custom lock-free structures, budget for a steeper learning curve in Rust. Plan to isolate that unsafe core behind stable APIs instead of expecting the whole stack to stay equally ergonomic.

      Attribution:
    • smj-edison #1 #2 #3
    • afdbcreid #1
    • nitros #1

Against the grain

  1. 01

    Hardware faults still punch through language safety

    Rowhammer came up as a reminder that language-level memory safety is not the whole stack. Even ECC memory only mitigates some fault attacks and has published bypasses. That does not weaken the case for safer software languages much, but it does puncture any claim of absolute safety.

    For high-assurance systems, pair software hardening with hardware assumptions you have actually validated. If fault attacks are in scope, language migration alone is not your security plan.

      Attribution:
    • bloaf #1 #2
    • inigyou #1
  2. 02

    Unsafe escape hatches weaken Rust's absolutist claims

    A few comments took the post's premise seriously and argued that if the standard is "no escape hatches," then Rust, Go, Java, and C# all fail because they permit unsafe operations somewhere in the stack. That framing is harsher than most engineers will use, but it is useful when you care about institutional guarantees rather than average-case safety.

    If you operate under strict compliance or sandboxing requirements, define whether "safe by default" is enough or whether unsafe capability must be structurally forbidden. That policy choice changes which languages and runtimes are even eligible.

      Attribution:
    • yjftsjthsd-h #1 #2
    • saghm #1 #2

In plain english

ABI
Application Binary Interface, the low-level contract that determines whether compiled code works with a given Python version or system environment.
CBMC
C Bounded Model Checker, a verification tool that can mathematically check C programs for bugs and contract violations.
ECC
Error-Correcting Code memory, hardware memory that can detect and often correct some bit errors.
fat pointers
Pointers that carry extra metadata, such as bounds information, instead of storing only a raw memory address.
FFmpeg
A widely used open source multimedia framework for decoding, encoding, and processing audio and video.
Fil-C
A project that runs C code with added runtime memory-safety checks using a custom runtime and application binary interface.
invisicaps
Fil-C's mechanism for attaching hidden capability and bounds metadata to pointers and allocations.
Kani
A model checker for Rust that can verify properties of Rust code across many execution paths.
libc
The standard C runtime library that provides core functions like memory allocation, strings, and input and output.
Rowhammer
A hardware attack that flips bits in memory by repeatedly accessing nearby rows of DRAM cells.

Reference links

Fil-C and related memory-safety mechanisms

Rust unsafe and low-level programming resources

Formal verification and research papers

Unsafe APIs in managed languages