Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • Great effort, but I find the whole idea somewhat flawed. If one needs speed, he can't use this C implementation, because it's several times slower. If speed isn't important, why not just using a memory safe language? And if both are important, why not using Rust?

    Recompiling existing software written in C using Fil-C isn't also a great idea, since some modifications are likely needed, at least for fixing bugs found with usage of Fil-C. And after these bugs are fixed, why continue using Fil-C?

  • You're glossing over the "just rewrite everything in Rust" part.
  • Security issues happen because of the bugs you won’t find under any normal use or with any tests you have

    That’s why even and especially if a C program runs in Fil-C with zero changes, you should use the Fil-C version in any context where security matters

  • And after these bugs are fixed, why continue using Fil-C?

    Because Fil-C might be a good way to debug future code?

    Your question reads like, "Why use a debugger?"

  • Safety isn’t really optional. Up until now, we’ve had no choice but to run C and accept the bugs; now we’re allowed to also run it safely.

    Yes, this means that C is one of the slower languages around. That’s fine; computers are fast. If you want to write high-performance code, there are plenty of faster languages to do it with.

  • You could use Fil-C in combination with a memory-safe language like Rust to allow for both "safe" leaf references (potentially using ownership and reference counting to represent more complex allocated objects, but would not themselves "own" pointers to Fil-C-managed data, thus avoiding the need to trace inside these objects and auto-free them) and general Fil-C managed pointers with possible cycles (perhaps restricted to some arena/custom address space, to make tracing and collecting more efficient) to be contained in a singke origram. Due to memory safety, the use of "leaf" references could be ensured not to alter the invariants that Fil-C relies on; but managed pointers would nonetheless be available whenever tracing GC could not be avoided.

    This would ultimately save much of the overhead associated with tracing GC itself.

  • Most software works flawlessly without modifications on Fil-C, the performance isn't *that* bad and there are applications where security is more important than performance (for example military applications)
  • Every time I read C and memory safety, I just think Golang. Especially for user space
  • Yes, think of something like Inferno, but Limbo now is AOT compiled instead of JITed.

    However there are also kernel like commercial projects in Go, and apparently the related TamaGo fork might eventually get upstreamed into the reference implementation.

    https://www.withsecure.com/en/solutions/innovative-security-...

  • Go programs are not fully memory-safe if they use multiple treads, due to possible data races with fat pointers: https://news.ycombinator.com/item?id=44672003
  • TLDR: 4x slowdown in the normal case

    the performance overhead of this approach for most programs makes them run about four times more slowly

  • > TLDR: 4x slowdown in the normal case

    4x slower isn't the normal case. 4x is at the upper end of the overheads you'll see.

  • posted multiple times, x86 only last time I checked
  • All the more reason to make it portable. I wonder if this can be implemented via LLVM?
  • Yeah because I’m limiting my test matrix.

    There’s nothing about how Fil-C is designed that constrains it to x86_64. It doesn’t strongly rely on x86’s memory model. It doesn’t strongly rely on 64-bit.

    I’m focusing on one OS and arch until I have more contributors and so more bandwidth to track bugs across a wider set of platforms.

  • Somewhat related, safe C++ proposal is not being continued

    https://news.ycombinator.com/item?id=45234460

  • I worked with the author of Fil-C at Apple while on the Safari team, and he's easily one of the brightest folks I've had the pleasure of knowing. Fil-C looks extremely cool.
    by cjk
  • Extraordinary project. I had several questions which I believe I have answered for myself (pizlonator please correct if wrong):

    1. How do we prevent loading a bogus lower through misaligned store or load?

    Answer: Misaligned pointer load/stores are trapped; this is simply not allowed.

    2. How are pointer stores through a pointer implemented (e.g. `*(char **)p = s`) - does the runtime have to check if *p is "flight" or "heap" to know where to store the lower?

    Answer: no. Flight (i.e. local) pointers whose address is taken are not literally implemented as two adjacent words; rather the call frame is allocated with the same object layout as a heap object. The flight pointer is its "intval" and its paired "lower" is at the same offset in the "aux" allocation (presumably also allocated as part of the frame?).

    3. How are use-after-return errors prevented? Say I store a local pointer in a global variable and then return. Later, I call a new function which overwrites the original frame - can't I get a bogus `lower` this way?

    Answer: no. Call frames are allocated by the GC, not the usual C stack. The global reference will keep the call frame alive.

    That leads to the following program, which definitely should not work, and yet does. ~Amazing~ Unbelievable:

        #include <stdio.h>
        
        char *bottles[100];
        
        __attribute__((noinline))
        void beer(int count) {
            char buf[64];
            sprintf(buf, "%d bottles of beer on the wall", count);
            bottles[count] = buf;
        }
        
        int main(void) {
            for (int i=0; i < 100; i++) beer(i);
            for (int i=99; i >= 0; i--) puts(bottles[i]);
        }
  • Hmmm ... there's a danger here that people will test their programs compiled with Fil-C and think that they are safe to compile with a "normal" compiler. I would hope for an option to flag any undefined behavior.
  • No discussion, but just on the front page last week (31 points) https://news.ycombinator.com/item?id=45655519

    Previous discussion:

    2025 Safepoints and Fil-C (87 points, 1 month ago, 44 comments) https://news.ycombinator.com/item?id=45258029

    2025 Fil's Unbelievable Garbage Collector (603 points, 2 months ago, 281 comments) https://news.ycombinator.com/item?id=45133938

    2024 The Fil-C Manifesto: Garbage In, Memory Safety Out (13 points, 17 comments) https://news.ycombinator.com/item?id=39449500

  • Either Fil-C or a different implementation of the same idea seems essential to me. A great deal of software has been written in C, and without some way of running it, we lose access to that intellectual heritage. But pervasive security vulnerabilities mean that the traditional "YOLO" approach to C compilation is a bad idea for software that has to handle untrusted input, such as Web browsing or email.

    Pizlo seems to have found an astonishingly cheap way to do the necessary pointer checking, which hopefully I will be able to understand after more study. (The part I'm still confused about is how InvisiCaps work with memcpy.)

    tialaramex points out that we shouldn't expect C programmers to be excited about Fil-C. The point tialaramex mentions is "DWIM", like, accessing random memory and executing in constant time, but I think most C programmers won't be willing to take a 4× performance hit. After all, if they wanted to be using a slow language, they wouldn't be writing their code in C. But I think that's the wrong place to look for interest: Fil-C's target audience is users of C programs, not authors of C programs. We want the benefits of security and continued usage of existing working codebases, without having to pay the cost to rewrite everything in Rust or TypeScript or whatever. And for many of us, much of the time, the performance hit may be acceptable.

  • > but I think most C programmers won't be willing to take a 4× performance hit.

    At a 4x performance hit, you might as well use C# or Go.

    > Fil-C's target audience is users of C programs, not authors of C programs.

    Sure, but then they don't get it for free. There is a perf penalty from GC. Plus you need all the original sources, right?

    > we lose access to that intellectual heritage.

    Declining usage of C is going to make you lose intellectual heritage[1]. A language no one can read or write is a dead language, regardless if you can translate it to English or not.

    [1] And that is outside Rust's or Zig's influence. It's an old language from when people thought you can trust the programmer. Which may well be the case if only people using it were Bell Labs engineers. It's got UB up the wazoo, no safety, and no sane package manager.

    by Ygg2
  • Also this is _de facto_ limited to userspace application for the mainstream OSes if my understanding is correct.

    Reading Fil-C website's "InvisiCaps by example" page, I see that "Laundering Integers As Pointers" is disallowed. This essentially disqualifies Fil-C for low-level work, which makes for a substantial part of C programs.

    (int2ptr for MMIO/pre-allocated memory is in theory UB, in practice just fine as long as you don't otherwise break aliasing rules (and lifetime rules in C++) - as the compiler will fail to track provenance at least once).

    But that isn't really what Fil-C is aimed at - the value is, as you implied, in hardening userspace applications.

  • I like to share this every time there's a post about memory safe C:

    Apple has a memory-safer C compiler/variant they use to compile their boot loaders:

    https://saaramar.github.io/iBoot_firebloom/

  • I'm working on packaging Fil-C for Nix, as well as integrating Fil-C as a toolchain in Nix so you can build any Nix package with Fil-C.

    https://github.com/mbrock/filnix

    It's working. It builds tmux, nethack, coreutils, Perl, Tcl, Lua, SQLite, and a bunch of other stuff.

    Binary cache on https://filc.cachix.org so you don't have to wait 40 minutes for the Clang fork to build.

    If you have Nix with flakes on a 64-bit Linux computer, you can run

        nix run github:mbrock/filnix#nethack
    
    right now!
  • That's very exciting! Thank you!
  • That is super cool, and I will probably start running it on at least a test box shortly.

    How does python work? Of course I can just add filc.python to my system, but if I `python3 -m pip install whatever` will it just rebuild any C modules with the fil-c compiler?

  • Yeah, I was thinking nix will be probably one of the first things that can easily adapt Fil-C as it already packages in a way that allows different packages to be completely independent of each other, thus Fil-C's ABI compatibility does not matter. I assume other targets will be mostly enterprise distros where the perf hit and source compatibility issues are less of a concern, and memory safety is absolutely critical.

    Fil-C compiled flatpaks might be a interesting target as well for normal desktop users. (e.g. running a browser)

    I wonder if GPU graphics are possible in Fil-C land? Perhaps only if whole mesa stack is compiled using Fil-C as well, limiting GPU use to open drivers?