Skip to content

[FEATURE] ZenC and FilC #315

@Macho0x

Description

@Macho0x

Proposal: Integrating Native Fil-C Compilation Support into ZenC for Enhanced Memory Safety

As a fan of ZenC's approach to blending high-level language ergonomics (like type inference, generics, traits, pattern matching, async/await, and RAII-style resource management) with zero-overhead performance and seamless C ABI compatibility, I'm exploring ways to further strengthen its safety guarantees. ZenC already compiles to human-readable C11 code, which can then be built with backends like GCC, Clang, Zig, or TCC. However, with growing concerns around memory safety in systems programming—highlighted by vulnerabilities in traditional C/C++ codebases—I'm wondering if it would make sense to add native support for compiling ZenC-generated code via Fil-C.

For context, Fil-C is a memory-safe fork of Clang (based on version 20.1.8) that enforces strict memory safety rules at compile time and runtime, while maintaining "fanatical" compatibility with existing C and C++ code. It achieves this through an LLVM pass called the "FilPizlonator," which transforms code to follow a "garbage in, memory safety out" model: either the compilation fails if safety can't be guaranteed, or the output adheres to Fil-C's memory safety doctrine (e.g., bounds checking, invisible capabilities for pointers, and panic-on-violation semantics). Notably, Fil-C supports unmodified compilation of complex projects like CPython, SQLite, OpenSSH, and Bash, with performance overhead typically ranging from 1x to 4x compared to standard Clang, depending on the workload.

Why Consider This Integration?

  • Enhanced Safety Without Rewrites: ZenC's generated C code could benefit from Fil-C's automatic memory safety injections, reducing risks like buffer overflows, use-after-free, or dangling pointers—common in low-level systems code. This aligns with ZenC's goal of making systems programming more accessible and reliable, especially for users targeting security-critical applications (e.g., networking, embedded systems, or game development).

  • Cross-Platform and Tooling Synergies: ZenC already supports portable builds via Cosmopolitan Libc (APE) across multiple OSes (Linux, macOS, Windows, BSD variants). Fil-C's compatibility with existing C runtimes and libraries could extend this, potentially allowing ZenC users to produce binaries that are both high-performance and provably memory-safe. Additionally, Fil-C's modern tooling (e.g., integration with Nix for packaging) could complement ZenC's LSP, REPL, and build directives.

  • Performance Trade-Offs as an Option: While Fil-C introduces some overhead (e.g., 2x-4x in graph-heavy or interpreter-like workloads), it could be offered as an optional flag (e.g., zc build --filc or --safe-backend). This keeps ZenC's default zero-overhead ethos intact for performance-sensitive users, while providing a "safety mode" for others. Benchmarks from Fil-C show it's viable for many real-world apps without degrading user experience.

  • Broader Ecosystem Benefits: Integrating Fil-C could position ZenC as a bridge between high-level safety-focused languages (like Rust) and legacy C ecosystems. For instance, ZenC's C interoperability (e.g., trusted header imports, FFI, inline assembly, CUDA/Objective-C support) could be leveraged to safely wrap unsafe C libraries, making ZenC more appealing for projects migrating from pure C.

Potential Challenges and Trade-Offs:

  • Compilation Overhead: Adding Fil-C as a backend might increase build times due to its additional LLVM passes. How feasible is this for ZenC's frontend, which focuses on generating clean C code?

  • Compatibility Edge Cases: Fil-C aims for zero-changes compilation, but some ZenC features (e.g., manual memory management with defer/autofree, SIMD intrinsics, or comptime code gen) might trigger panics or require tweaks. Has anyone tested ZenC output with Fil-C already?

  • Dependencies and Portability: Fil-C requires a custom libc setup (yolo libc for bootstrapping and user libc for runtime). This could complicate ZenC's minimal dependency model or APE portability—would it necessitate bundling Fil-C components?

  • Performance in Specific Use Cases: For ZenC's targets like game dev (e.g., ZC-pong-3ds) or high-perf computing, the 1x-4x slowdown might be unacceptable in some scenarios. Could optimizations (e.g., selective safety disabling via pragmas) mitigate this?

Questions for Discussion:

  1. Does this integration align with ZenC's philosophy of "write like a high-level language, run like C"? Or would it dilute the focus on performance and simplicity?
  2. Technically, how could we implement this? For example, by adding a new build flag that pipes ZenC's C output directly to filcc instead of clang or gcc?
  3. Are there existing examples or proofs-of-concept where languages/compilers like ZenC have adopted memory-safe backends (e.g., similar to Rust's safe/unsafe dichotomy)?
  4. What benchmarks or tests would be needed to evaluate feasibility? I'd be happy to contribute if there's interest.
  5. Alternatives: Instead of native integration, should users just manually compile ZenC output with Fil-C? Or explore other safety tools like Checked C or TrapC?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions