A simplified model of Fil-C
Fil-C is presented as a way to compile existing C programs into a memory-safe form, trading higher runtime and memory overhead for automatic bounds checking, garbage collection, and strong isolation, without requiring a rewrite into a new language. Commenters contrast this runtime-enforced safety with Rust’s largely compile-time guarantees, debating performance costs, lack of seamless interop with non–Fil-C code, and the impact of crashes-as-safety on reliability for services. The conversation also touches on potential hardware support for capabilities and garbage collection, and notes open limitations such as behavior under data races.
Perceived role of Fil-C
- Seen by some as an underrated way to harden existing C/C++ code without a risky rewrite.
- Especially attractive for long-lived, battle‑tested C utilities where extra latency and memory are acceptable.
- Others stress that it targets a different niche than languages like Rust or Ada; not a general replacement.
Performance and overhead
- Widely acknowledged that Fil-C is “quite a bit slower” and uses more memory than native C or Rust.
- Authorial comments suggest an aspirational overhead in the ~20–30% range for many workloads, which some consider acceptable for the safety gained.
- Critics argue that if you accept that level of overhead, managed languages (Java, C#, Go) or rewrites may also be on the table.
Interop, platform constraints
- Major downside: Fil-C does not interoperate with non‑Fil‑C code, not even libc.
- This complicates use on non-Linux platforms and mixing with other safe languages or native APIs.
- Workarounds like an FFI to “unsafe C” are considered possible but intentionally avoided so far.
Runtime vs compile-time safety
- Fil-C enforces memory safety at runtime: unsafe operations crash instead of corrupting memory.
- Debate over whether “crash-only” behavior counts as memory safe; consensus is that it is, but crashes can still be DOS vulnerabilities.
- Compared to Rust: Rust moves many checks to compile time and allows some runtime failures to be caught and recovered (panics, unwinding), which Fil-C currently does not.
- Some suggest signals or exceptions could be used for recovery in principle, but this is not the current design.
Garbage collection and real-time aspects
- Fil-C includes a concurrent, on-the-fly GC; some C/C++ programmers are enthusiastic, others say GC is incompatible with their real‑time needs.
- There is discussion of potential to make the GC real‑time friendly with more engineering effort.
Hardware support, fat pointers, and techniques
- Fil-C uses techniques related to fat pointers and shadow memory (“InvisiCaps”), but is described as more than just fat pointers.
- Some commenters note hardware trends (CHERI, memory tagging, experimental object-memory hardware) that could accelerate such schemes.
- Others point out that fat-pointer-like schemes have often been rejected historically due to ABI and overhead issues.
Tooling, ecosystem, and alternatives
- Some expect improved C tooling and formal verification to erode Rust’s safety advantage over time; others are skeptical that “automatic” formal verification will be simple.
- Rust, Go, managed languages, and specialized formally-verified DSLs (e.g., WUFFS, SPARK-like systems) are all mentioned as alternative safety strategies with different tradeoffs.
- A Bazel template for Fil-C is shared to ease hermetic builds.
Critiques and limitations
- Fil-C is reported not to be memory safe under data races; capability and pointer fields can tear under concurrent writes, leading to misbehavior.
- Some worry that runtime-only safety, lack of interop, and slower performance limit Fil-C to narrow use cases.
- Others emphasize that recompiling existing code with Fil-C (with no large rewrite) is itself a major practical advantage.