[HN Gopher] Ported freetype, fontconfig, harfbuzz, and graphite ...
___________________________________________________________________
Ported freetype, fontconfig, harfbuzz, and graphite to Fil-C
Author : jhatemyjob
Score : 42 points
Date : 2025-11-29 19:18 UTC (3 hours ago)
(HTM) web link (twitter.com)
(TXT) w3m dump (twitter.com)
| rvz wrote:
| What is the actual catch with Fil-C? Memory safety for C based
| projects without a complete rewrite sounds like a very good idea,
| but there must be some pitfalls in this approach which this would
| not work in some cases.
|
| In some other memory-safety circles (Rust, Zig, etc) I'm going to
| expect that this is going to be heavily scrutinized over the
| claims made by the author of Fil-C.
|
| But great work on this nonetheless.
| pizlonator wrote:
| Author here! :-)
|
| > What is the actual catch with Fil-C?
|
| Two things:
|
| - Not ABI compatible with Yolo-C. So, you have to recompile the
| whole stack. This is both a major catch, and it is both a bug
| and a feature. It's a bug for obvious reasons. It's a feature
| because it means I'll probably be the first to have a totally
| usable, totally memory safe desktop environment.
|
| - In my testing, it's between 1.2x and 4x slower than Yolo-C.
| It uses between 2x and 3x more memory. Others have observed
| higher overheads in certain tests (I've heard of some things
| being 8x slower). How much this matters depends on your
| perspective. Imagine running your desktop environment on a 4x
| slower computer with 3x less memory. You've probably done
| exactly this and you probably survived the experience. So the
| catch is: Fil-C is for folks who want the security benefits
| badly enough.
|
| It's not obvious that either of these catches are fundamental.
| The Fil-C development philosophy is very much to get something
| working first, which means downscoping. That's why I didn't
| include Yolo-C ABI compat as a goal at all and it's also why I
| haven't done as many optimizations as I should have. If you
| look at my GitHub you'll see >20 open issues with performance
| optimization ideas.
|
| > In some other memory-safety circles (Rust, Zig, etc) I'm
| going to expect that this is going to be heavily scrutinized
| over the claims made by the author of Fil-C.
|
| Of course this has happened.
|
| Zig is definitely not as safe as either Rust or Fil-C, since
| Zig doesn't have a great story for use after free.
|
| Rust is less safe than Fil-C in practice, because Rust code
| uses `unsafe` a lot (>100 uses of `unsafe` in uutils and sudo-
| rs, for example), and Rust code ends up depending on an unsafe
| stack (like calling into libc, but also lots of other dependent
| libraries that are written in C). Fil-C doesn't have an
| `unsafe` statement and the dependencies are all recompiled with
| Fil-C.
| IshKebab wrote:
| > Zig is definitely not as safe as either Rust or Fil-C,
| since Zig doesn't have a great story for use after free.
|
| Have you considered making... Fil-Zig? Would it be easier to
| do because Zig is already fairly far ahead of C in terms of
| safety?
|
| > Rust is less safe than Fil-C in practice, because Rust code
| uses `unsafe` a lot (>100 uses of `unsafe` in uutils and
| sudo-rs, for example), and Rust code ends up depending on an
| unsafe stack (like calling into libc, but also lots of other
| dependent libraries that are written in C).
|
| To be fair `sudo-rs`'s usage of unsafe is all there just to
| interface with C code (e.g. PAM) so it isn't really sudo-rs
| that is "less safe", it's just that PAM isn't any safer
| (because it's unmodified C). Also you _can_ use Rust without
| libc - https://github.com/sunfishcode/mustang - unfortunately
| it doesn't seem to have gained much traction which I think is
| a shame because glibc is a curse.
|
| Most Rust programs actually have very few C dependencies. The
| big exceptions are libc and OpenSSL, but I think they'll be
| excised eventually.
| pizlonator wrote:
| > To be fair `sudo-rs`'s usage of unsafe is all there just
| to interface with C code (e.g. PAM) so it isn't really
| sudo-rs that is "less safe"
|
| That's exactly my point.
|
| sudo compiled with Fil-C: uses pam compiled with Fil-C, and
| all of pam's dependencies are compiled with Fil-C, so the
| whole thing is memory safe.
|
| sudo-rs: uses pam compiled with Yolo-C, so it's not
| actually safe. pam is quite big and pulls in other unsafe
| dependencies
| Ar-Curunir wrote:
| Almost all uses of unsafe in Rust are either for FFI, or to
| avoid the overhead of things like ref-counting. If you use,
| eg, Rc RefCell everywhere you will achieve safety without
| issue.
| pizlonator wrote:
| > Almost all uses of unsafe in Rust are either for FFI
|
| Which makes Rust less safe than Fil-C.
|
| Consider that you have a dependency like libc, PAM,
| openssl, or the like.
|
| In Rust: you will `unsafe` call into the unsafe versions of
| those libraries. Hence, even if your Rust code is safe in
| isolation, your program is not safe overall because you're
| pulling in unsafe code.
|
| In Fil-C: compile those dependencies with Fil-C, and then
| the whole process is safe.
| josephg wrote:
| > In Fil-C: compile those dependencies with Fil-C, and
| then the whole process is safe.
|
| Great work on Fil-C by the way. Very technically
| impressive stuff!
|
| It seems like the competition for Fil-C is other garbage
| collected languages. Rust will always outperform Fil-C,
| with the caveat that rust allows unsafe blocks, raw
| pointers and raw C FFI. But if you're happy to ditch
| performance and the ability to do bare metal systems
| level programming, why Fil-C over Go or C#?
|
| If you want a safer, less convenient dialect of rust,
| that also exists. Just don't use or depend on any unsafe
| code in your program. (There are 3rd party tools to check
| this). More and more C libraries are getting pure rust
| ports these days. It's increasingly rare to actually need
| to pull in C libraries at all. Sticking to safe rust is a
| bit inconvenient - but I suspect so is using fil-c. I
| suppose with fil-C you can use any libraries you want,
| you've just gotta recompile them. That's cool!
|
| Rust has a bunch of unsafe code in std, so you're still
| at risk of a bug there causing safety problems. But the
| same is true of Fil-C.
|
| I could definitely see myself reaching for Fil-C when
| running legacy code. It'd be nice if there was a way to
| use fil-C to protect my rust program from memory bugs in
| C dependencies. But I can think of dozens of ways why
| that would be tricky to pull off.
|
| Also I'm curious - can Fil-C protect against threading
| bugs like rust can? Rust has Send & Sync traits to mark
| which objects can be safely shared between threads. I
| can't think of a way to do that in an automated way
| without help from the programmer.
| drnick1 wrote:
| > More and more C libraries are getting pure rust ports
| these days.
|
| I don't think these rewrites will ever be mainstream.
| There is so much C out there, and typically ports focus
| on the 90% that is easy to write and neglect the
| remaining 10%.
| pizlonator wrote:
| > It seems like the competition for Fil-C is other
| garbage collected languages. Rust will always outperform
| Fil-C, with the caveat that rust allows unsafe blocks,
| raw pointers and raw C FFI. But if you're happy to ditch
| performance and the ability to do bare metal systems
| level programming, why Fil-C over Go or C#?
|
| Say you wanted to write a tool like sudo in C# or Go.
| Here's what would happen: you'd end up having to rely on
| dependent libraries, like pam, which then relies on other
| things like libselinux and libaudit. And libselinux
| depends on pcre2. Those things would be compiled with
| Yolo-C, so while your sudo tool's new code written by you
| would be safe, the process would mostly contain unsafe
| code.
|
| But if you write sudo in Fil-C, then you can rely on all
| of those dependencies being compiled with Fil-C. The
| whole process is safe.
|
| So, the reason why you'd pick Fil-C is that it's actually
| memory safe for real, unlike the alternatives, which just
| give you safety for newly written code but pull in a ton
| of unsafe depenendencies.
|
| > If you want a safer, less convenient dialect of rust,
| that also exists. Just don't use or depend on any unsafe
| code in your program. (There are 3rd party tools to check
| this).
|
| That's impractical for the reasons above.
|
| > Also I'm curious - can Fil-C protect against threading
| bugs like rust can?
|
| Not like Rust can, but yes, it does.
|
| Fil-C preserves memory safety under races. This means
| that debugging multithreaded C/C++ programs in Fil-C is a
| much nicer experience than in Yolo-C. If you do something
| wrong, you're going to get a panic - similar to how
| multithreading bugs in Java or C# lead to exceptions.
|
| But, unlike Rust, Fil-C does not attempt to ensure race-
| freedom for your own logic.
| josephg wrote:
| > What is the actual catch with Fil-C?
|
| It sounds like Fil-C combines the ergonomics of C with the
| performance of Python.
|
| It might have a beautiful niche for safely sandboxing legacy
| code. But I don't see any compelling reason to use it for new
| code. Modern GC languages are much more ergonomic than C and
| better optimised. C#, Java, JavaScript and Go are all easier to
| write, they have better tooling and they will probably all
| perform as well or better than Fil-C in its current state.
| o11c wrote:
| I was reading the `fontconfig` source recently (to help me
| understand what, exactly, is the difference between the various
| `fc-*` tools and their options) and some of the code scared me.
|
| I thought, "for sure this is a use-after-free" ... but it
| happened to be safe because some function performed an
| undocumented incref, and the return value of that function was
| kept alive.
|
| So this is definitely a high priority thing to port!
|
| ... I suppose the interesting question is: if some of my
| dependencies are ported, and some are not, is there any way a
| normal compiler can call into a Fil-C-compiled library for just a
| few functions?
| woodruffw wrote:
| > ... I suppose the interesting question is: if some of my
| dependencies are ported, and some are not, is there any way a
| normal compiler can call into a Fil-C-compiled library for just
| a few functions?
|
| To my understanding, there's no way to do this: Fil-C is
| basically a managed runtime for native code, so the FFI
| implications are similar to those for Go or any other intrusive
| managed runtime. Which is to say that Fil-C could offer an FFI,
| but not without losing the blanket exit-instead-of-memory-
| unsafety guarantees it aims to offer.
| pizlonator wrote:
| Exactly right
| malkia wrote:
| If Fil-C requires complete recompile of ".c" code how does it
| deal with calls to the OS - Does it rewrap them (like Go?). I'm
| bit uncertain here...
| o11c wrote:
| It uses a sandwich; see https://fil-c.org/runtime
___________________________________________________________________
(page generated 2025-11-29 23:01 UTC)