[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)