A simplified model of Fil-C
Posted by aw1621107 12 hours ago
Comments
Comment by hsaliak 9 hours ago
Comment by avadodin 2 hours ago
It leaves room for experimentation with reference counting and variations on the invisible capability system which could provide memory savings at the expense of some extra indirection.
Comment by teo_zero 2 hours ago
> Upon freeing an unreachable AllocationRecord, call filc_free on it.
I think the intention was to say: before freeing an unreachable AR, free the memory pointed to by its visible_bytes and invisible_bytes fields.
Comment by whatsakandr 12 hours ago
Comment by tialaramex 11 hours ago
1. Fil-C is slower and bigger. Noticeably so. If you were OK with slower and bigger then the rewrite you should have considered wasn't to Rust in the last ten years but to Java or C# much earlier. That doesn't invalidate Fil'C's existence, but I want to point that out.
2. You're still writing C. If the program is finished or just occasionally doing a little bit of maintenance that's fine. I wrote C for most of my career, it's not a miserable language, and you are avoiding a rewrite. But if you're writing much new code Rust is just so much nicer. I stopped writing any C when I learned Rust.
3. This is runtime safety and you might need more. Rust gives you a bit more, often you can express at compile time things Fil-C would only have checked at runtime, but you might need everything and languages like WUFFS deliver that. WUFFS doesn't have runtime checks. It has proved to its satisfaction during compilation that your code is safe, so it can be executed at runtime in absolute safety. Your code might be wrong. Maybe your WUFFS GIF flipper actually makes frog GIFs purple instead of flipping them. But it can't crash, or execute x86 machine code hidden in the GIF, or whatever, that's the whole point.
Comment by whatsakandr 10 hours ago
I'm not convinced that tying the lifetimes into the type system is the correct way to do memory management. I've read too many articles of people being forced into refactoring the entire codebase to implement a feature.
Comment by saghm 4 hours ago
Comment by brucehoult 9 hours ago
Not some random dad, but a GC expert and former leader of the JavaScript VM team at Apple.
Comment by fooker 3 hours ago
Type systems used to be THE sexy PL research topic for about twenty years or so, so all the programming languages innovation has been about doing everything with type systems.
Comment by achierius 9 hours ago
Comment by gmueckl 8 hours ago
Comment by cxr 8 hours ago
It's not any slower or (proportionally) bigger compared to the experience you would have had 20 years ago running all sorts of utilities that happen to be the best candidates for Fil-C, and people got along just fine. How fast do ls and mkdir need to be?
Comment by adgjlsfhk1 5 hours ago
Comment by nlitened 3 hours ago
Comment by adrianN 3 hours ago
Comment by IshKebab 4 hours ago
If you tell your boss "We spent $1m on servers this month and that's as cheap as its possible to be" he'll be like "ok fine". If you say "We spent $1m on servers this month but if we just disable this compiler security flag it could be $500k." ... you can guess what will happen.
(Counterpoint though: people use Python.)
But counter-counterpoint: Rust does so much more than preventing runtime memory errors. Even if Fil-C had no overhead (or I was using CHERI) I would still use Rust.
Comment by cxr 1 hour ago
It sure does. Like making your build times slower (and bigger) than if you were using the equivalent tooling for Pascal, C, or Zig.
Comment by aw1621107 3 minutes ago
I think GP is talking about not-directly-related-to-safety things like sum types/pattern matching/traits/expressive type systems/etc. given the end of that paragraph. I don't think you can get "equivalent tooling" for such things the languages you list without raising interesting questions about what actually counts as Pascal/C/Zig.
Comment by blub 4 hours ago
Rust has managed to establish itself as a player, but it’s only the best choice for a limited amount of projects, like some (but not all) browser code or kernel code. Go, C++, C with Fil-C) have solid advantages of their own.
To name two:
* idiomatic code is easier to write in any of these languages compared to Rust, because one can shortcut thinking about ownership. Rust idiomatic code requires it.
* less effort needed to protect from supply-chain attacks
Comment by tobias12345 3 hours ago
I have seen so must stuff copy and pasted into projects in my life, its not funny. Often it is undocumented where exactly the code comes from, which version it was taken from, how it was changed, and how to update it when something goes wrong.
When code is not copy and pasted it is over rewritten (poorly).
Code sharing does have its benefit. So does making it obvious which exact code is shared and how to update it. Yes, you can overdo code sharing, but just making code sharing hard on the tooling level does mote to hide supply chain security issues than it does to prevent the problem.
Comment by pjmlp 1 hour ago
As my comment history reveals I am more on the camp of having rewrites in Go (regardless of my opinion on its design), Java, C#, Haskell, OCaml, Lisp, Scheme,... Also following experiments of Cedar, Oberon, Singularity, Interlisp-D, StarLisp,....
However you will never convince someone anti-automatic resource management from ideological point of view.
Now would someone like that embrace Fil-C, with its sandboxing and GC? Maybe not, unless pushed from management kind of decision.
They would probably rewrite in Rust, Zig, Odin,... if those are appealing to them, or be faced with OS vendors pushing hardware with SPARC ADI, CHERI, ARM MTE,... enabled.
Comment by tobias12345 3 hours ago
Comment by up2isomorphism 7 hours ago
Comment by gnabgib 12 hours ago
Fil-Qt: A Qt Base build with Fil-C experience (143 points, 3 months ago, 134 comments) https://news.ycombinator.com/item?id=46646080
Linux Sandboxes and Fil-C (343 points, 4 months ago, 156 comments) https://news.ycombinator.com/item?id=46259064
Ported freetype, fontconfig, harfbuzz, and graphite to Fil-C (67 points, 5 months ago, 56 comments) https://news.ycombinator.com/item?id=46090009
A Note on Fil-C (241 points, 5 months ago, 210 comments) https://news.ycombinator.com/item?id=45842494
Notes by djb on using Fil-C (365 points, 6 months ago, 246 comments) https://news.ycombinator.com/item?id=45788040
Fil-C: A memory-safe C implementation (283 points, 6 months ago, 135 comments) https://news.ycombinator.com/item?id=45735877
Fil's Unbelievable Garbage Collector (603 points, 7 months ago, 281 comments) https://news.ycombinator.com/item?id=45133938
Comment by omcnoe 11 hours ago
Guaranteed memory safety at compile time is clearly the better approach when you care about programs that are both functionally correct and memory safe. If I'm writing something that takes untrusted user input like a web API memory safety issues still end up as denial-of-service vulns. That's better, but it's still not great.
Not to disparage the Fil-C work, but the runtime approach has limitations.
Comment by pizlonator 11 hours ago
If it's guaranteed to crash, then it's memory-safe.
If you dislike that definition, then no mainstream language is memory-safe, since they all use crashes to handle out of bounds array accesses
Comment by omcnoe 11 hours ago
Other languages have runtime exceptions on out-of-bounds access, Fil-C has unrecoverable crashes. This makes it pretty unsuitable to a lot of use cases. In Go or Java (arbitrary examples) I can write a web service full of unsafe out-of-bounds array reads, any exception/panic raised is scoped to the specific malformed request and doesn't affect the overall process. A design that's impossible in Fil-C.
Comment by wren6991 8 hours ago
Comment by dzaima 11 hours ago
try-catch isn't a particularly complete solution either if you have any code outside of it (at the very least, the catch arm) or if data can get preserved across iterations that can easily get messed up if left half-updated (say, caches, poisoned mutexes, stuck-borrowed refcells) so you'll likely want a full restart to work well too, and might even prefer it sometimes.
Comment by wakawaka28 11 hours ago
Comment by pizlonator 10 hours ago
I just don’t like that design. It’s a matter of taste
Comment by wakawaka28 6 hours ago
Comment by ori_b 11 hours ago
Comment by p1necone 10 hours ago
(Also I think the commenter you're replying to just worded their comment innacurately, code that crashes instead of violating memory safety is memory safe, a compilation error would just have been more useful than a runtime crash in most cases)
Comment by DetroitThrow 10 hours ago
Comment by 100ms 11 hours ago
https://play.rust-lang.org/?version=stable&mode=debug&editio...
Comment by touisteur 3 hours ago
Comment by zamadatix 11 hours ago
- Explicitly unsafe
- Runtime crash
- Runtime crash w/ compile time avoidence when possible
Comment by omcnoe 11 hours ago
Catch the panic & unwind, safe program execution continues. Fundamentally impossible in Fil-C.
Comment by uecker 10 hours ago
Comment by jz391 6 hours ago
Comment by wakawaka28 11 hours ago
Comment by omcnoe 10 hours ago
I also don't think it's that niche a use case. It's one encountered by every web server or web client (scope exception to single connection/request). Or anything involving batch processing, something like "extract the text from these 10k PDFs on disk".
Comment by wakawaka28 10 hours ago
Generally, I think one could want to recover from errors. But error recovery is something that needs to be designed in. You probably don't want to catch all errors, even in a loop handling requests for an application. If your application isn't designed to handle the same kinds of memory access issues as we're talking about here, the whole thing turns into non-existent-apples to non-existent-apples lol.
Comment by saghm 5 hours ago
> All this "rewrite it in rust for safety" just sounds stupid when you can compile your C program completely memory safe.
All of the points about Rust were made in that context, and they've pushed back against it successfully enough that now you're trying to argue from the other side as if it disproves their point. No one here is saying that there's no point in having safer C code or that literally everything needs to get rewritten; they're just pointing out that yes, there is a concrete advantage that something in Rust has over something in C today even with Fil-C available.
Comment by boredatoms 11 hours ago
Comment by forrestthewoods 11 hours ago
It’s true that, assuming all things equal, compile-time checks are better than run-time. I love Rust. But Rust is only practical for a subset of correct programs. Rust is terrible for things like games where Rust simply can not prove at compile-time that usage is correct. And inability to prove correctness does NOT imply incorrectness.
I love Rust. I use it as much as I can. But it’s not the one true solution to all things.
Comment by omcnoe 11 hours ago
But Rust provides both checked alternatives to indexed reads/writes (compile time safe returning Option<_>), and an exception recovery mechanism for out-of-bounds unsafe read/write. Fil-C only has one choice which is "crash immediately".
Comment by uecker 10 hours ago
Comment by omcnoe 10 hours ago
Comment by kimixa 8 hours ago
Programming languages have always been more about what they don't let you do rather than what they do - and where that lies on the spectrum of blocking "Possibly Valid" constructs vs "Possibly Invalid".
Comment by uecker 9 hours ago
Comment by tialaramex 9 hours ago
Comment by uecker 9 hours ago
Comment by wakawaka28 10 hours ago
And inability to prove incorrectness does NOT imply correctness. I think most Rust users don't understand either, because of the hype.
Comment by pizlonator 12 hours ago
> "rewrite it in rust for safety" just sounds stupid
To be fair, Fil-C is quite a bit slower than Rust, and uses more memory.
On the other hand, Fil-C supports safe dynamic linking and is strictly safer than Rust.
It's a trade off, so do what you feel
Comment by masfuerte 11 hours ago
ar->invisible_bytes = calloc(length, sizeof(AllocationRecord));Comment by pizlonator 11 hours ago
I am the author of Fil-C
If you want to see my write-ups of how it works, start here: https://fil-c.org/how
Comment by masfuerte 11 hours ago
Comment by dataflow 11 hours ago
When's the last time you told a C/C++ programmer you could add a garbage collector to their program, and saw their eyes light up?
Comment by pjmlp 1 hour ago
Windows developers using COM, and WinRT, Apple developers using IO and Driver Kit.
Comment by fulafel 7 hours ago
And of course it's easy to think of lots of apps that heavily use those or another form of GC.
Comment by dataflow 7 hours ago
Comment by FuckButtons 11 hours ago
Comment by brucehoult 9 hours ago
Comment by dataflow 7 hours ago
Comment by fweimer 6 hours ago
Comment by dataflow 3 hours ago
The GCC garbage collector GGC is only invoked explicitly. In contrast with many other garbage collectors, it is not implicitly invoked by allocation routines when a lot of memory has been consumed. [1]
[1] https://gcc.gnu.org/onlinedocs/gccint/Invoking-the-garbage-c...
Comment by pizlonator 11 hours ago
- Me. I'm a C++ programmer.
- Any C++ programmer who has added a GC to their C++ program. (Like the programmers who used the web browser you're using right now.)
- Folks who are already using Fil-C.
Comment by FuckButtons 11 hours ago
Comment by pizlonator 10 hours ago
My original foray into GCs was making real time ones, and the Fil-C GC is based on that work. I haven’t fully made it real time friendly (the few locks it has aren’t RT-friendly) but if I had more time I could make it give you hard guarantees.
It’s already full concurrent and on the fly, so it won’t pause you
Comment by cxr 8 hours ago
Comment by pjmlp 1 hour ago
Comment by Panzerschrek 5 hours ago
If new code needs to be written, there is no reason to use Fil-C, since better languages with build-in security mechanisms exist.
Comment by ekaryotic 1 hour ago
Comment by aw1621107 14 minutes ago
Comment by kbolino 11 hours ago
Comment by pizlonator 11 hours ago
Comment by kbolino 11 hours ago
Comment by pizlonator 11 hours ago
Here's why:
1. For the first year of Fil-C development, I was doing it on a Mac, and it worked fine. I had lots of stuff running. No GUI in that version, though.
2. You could give Fil-C an FFI to Yolo-C. It would look sort of like the FFIs that Java, Python, or Ruby do. So, it would be a bit annoying to bridge to native APIs, but not infeasible. I've chosen not to give Fil-C such an FFI (except a very limited FFI to assembly for constant time crypto) because I wanted to force myself to port the underlying libraries to Fil-C.
3. Apple could do a Fil-C build of their userland, and MS could do a Fil-C build of their userland. Not saying they will do it. But the feasibility of this is "just" a matter of certain humans making choices, not anything technical.
Comment by kvemkon 11 hours ago
Interesting, how costly would be hardware acceleration support for Fil-C code.
Comment by kbolino 11 hours ago
[1]: https://en.wikipedia.org/wiki/Capability_Hardware_Enhanced_R...
Comment by Findecanor 9 hours ago
There is a startup working on "Object Memory Addressing" (OMA) with tracing GC in hardware [1], and its model seems to map quite well to Fil-C's. I have also seen a discussion on RISC-V's "sig-j" mailing list about possible hardware support for ZGC's pointer colours in upper pointer bits, so that it wouldn't have to occupy virtual memory bits — and space — for those.
However, I think that tagged pointers with reference counting GC could be a better choice for hardware acceleration than tracing GC. The biggest performance bottleneck with RC in software are the many atomic counter updates, and I think those could instead be done transparently in parallel by a dedicated hardware unit. Cycles would still have to be reclaimed by tracing but modern RC algorithms typically need to trace only small subsets of the object graph.
[1]: "Two Paths to Memory Safety: CHERI and OMA" https://news.ycombinator.com/item?id=45566660
Comment by rvz 11 hours ago
Fil-C just does the job with existing software in C or C++ without an expensive and bug riddled re-write and serves as a quick protection layer against the common memory corruption bugs found in those languages.
Comment by uecker 10 hours ago
Comment by zozbot234 4 hours ago
Comment by uecker 3 hours ago
Comment by kobebrookskC3 5 hours ago
"simply" and "formal verification" are usually oxymorons, never mind "automatically"
Comment by uecker 4 hours ago
Comment by GaggiX 11 hours ago
Comment by DetroitThrow 11 hours ago
I love Fil-C. It's underrated. Not the same niche as Rust or Ada.
Comment by andai 10 hours ago
Comment by adamnemecek 10 hours ago
Comment by vzaliva 11 hours ago