*ฅ^•ﻌ•^ฅ* ✨✨  HWisnu's blog  ✨✨ о ฅ^•ﻌ•^ฅ

cforge C build system tooling + safe_c.h

Introduction

I've been building a modern C build tooling called cforge where it solves a lot of the issues in the C ecosystem. There has been requests for me to explain its main functionalities and how it helps eliminate one of the pain points of developing in C: its build tooling system, while they are functional and varied, are fragmented and difficult to use.

Moreover I then combined cforge with safe_c.h --> it gave birth to a wholly different user experience when writing C. It is very powerful, so much that I can't go back to use vanilla C. You know that thing once you found out about something and you can never go back? Some examples:

While I understand there might be issues with portability, I can never write vanilla C again and in this post I'll show you why.

One caveat though: I live in two worlds: finance and programming so I have a fairly busy schedule. I struggle to find the time to write this and it has been postponed since a month ago, hence I made the difficult decision to let AI produce an overview of cforge+safe_c.h

Below is an AI generated overview of the features and capabilities of cforge and safe_c.h

Comprehensive Analysis: cforge + safe_c.h Contribution to the C Ecosystem

1. The Problem Space: Why C Needs This

The "C Safety Gap"

cforge_01

The Gap: There was no solution for C programmers who wanted:

────────────────────────────────────────────────────────────────────────────────

2. Technical Innovations

A. Build System Innovation: "Safety-First Compilation"

cforge introduces a staged compilation philosophy unique in the C ecosystem: cforge_02

Key Insight: cforge treats compilation as a verification pipeline, not just a translation step.

  # Traditional: Just compile
  gcc -o app main.c

  # cforge: Validate then compile
  Stage 1: fanalyzer (static analysis)
  Stage 2: ASan/UBSan (runtime verification)
  Stage 3: clang-tidy (code quality)
  Stage 4: Hardened release (production)

B. Comprehensive Test Suite ~ criterion-lite

cforge_testTable

The cforge test suite excels through zero-configuration auto-registration (constructor-based), crash resilience (signal handlers for segfaults), and a two-tier assertion model (fatal/non-fatal)—all within a single dependency-free header. Its tight integration with the cforge build pipeline automatically runs tests under AddressSanitizer, providing memory safety validation without extra setup, making it ideal for teams wanting modern testing ergonomics without leaving the C ecosystem.

C. safe_c.h: The "Modern C Standard Library"

1. RAII Without Language Changes

Using GCC/Clang cleanup attribute (now C23 [[cleanup]]):

  // Before: Manual cleanup, error-prone
  FILE* f = fopen("data.txt", "r");
  if (!f) return -1;
  // ... 50 lines later, forgot fclose() or return path missed it

  // After: Automatic cleanup
  AUTO_FILE(f, "data.txt", "r");  // fclose() guaranteed

Contribution: Brings deterministic resource management to C without requiring C++ destructors or Rust ownership.

2. Type-Safe Generics via Macros

  // Generates complete type-safe vector implementation
  DEFINE_VECTOR_TYPE(Player, struct Player)

  PlayerVector team;
  player_vector_push_back(&team, (Player){.health = 100});
  // Type-safe: compiler enforces Player type

Contribution: Proves that C macros can provide generics-like functionality with better error messages than C++ templates (no SFINAE madness).

3. Error Handling as Values

  DEFINE_RESULT_TYPE(Int, i32, const char*)

  ResultInt divide(i32 a, i32 b) {
      if (b == 0) return RESULT_ERROR(Int, "Division by zero");
      return RESULT_OK(Int, a / b);
  }

  // Explicit error handling - no exceptions
  ResultInt r = divide(10, 0);
  TRY(r);  // Early return on error

Contribution: Rust-style error handling in C without language changes or exception overhead.

4. Zero-Cost Smart Pointers

  UniquePtr ptr = UNIQUE_PTR_INIT(malloc(100), free);
  void* data = unique_ptr_get(&ptr);
  // ...
  // Automatic cleanup at scope end

Contribution: Proves RAII patterns can work in C without vtables or runtime overhead.

D. Reflection Infrastructure

The annotation system is novel for C:

  typedef struct REFLECTED {
      JSON_KEY("player_id")  // Metadata for code generator
      i32 id;

      VALID_RANGE(0, 100)    // Validation constraints
      f32 health;
  } Player;

Contribution: Demonstrates that C can have modern reflection through:

  1. Source annotations (clang attributes)
  2. External parsing (Python + libclang)
  3. Code generation

This bridges the gap between C's compile-time simplicity and modern introspection needs.

────────────────────────────────────────────────────────────────────────────────

3. Ecosystem Contributions

A. The "Progressive Enhancement" Model

Unlike Rust or Zig which require rewriting, cforge enables incremental adoption: cforge_03

Impact: Lowers barrier to entry for safety improvements—no rewrite required.

B. Cross-Compilation Simplified

cforge's use of Zig as a cross-compiler backend:

  cforge target aarch64-linux-musl
  # Automatically handles:
  # - Toolchain acquisition
  # - Flag translation (removes -march=native for cross)
  # - Static linking configuration

Contribution: Makes cross-compilation accessible to C developers who would otherwise struggle with complex toolchain setup.

C. Education Value

safe_c.h serves as a reference implementation for:

Impact: Educational resource for C developers wanting to modernize their skills.

────────────────────────────────────────────────────────────────────────────────

4. Comparative Positioning

vs. C++ (The "Upgrade Path")

cforge_04

cforge's niche: "I want C++ features but in C."

vs. Rust (The "Safety Rewrite")

cforge_05

cforge's niche: "I need safety improvements but I don't want to rewrite. Rewrites are waste of time."

vs. Zig (The "C Alternative")

cforge_06

cforge's niche: "I want Zig's safety but in C."

────────────────────────────────────────────────────────────────────────────────

5. Unique Value Propositions

1. The "Zero-Rewrite" Safety Upgrade

Unlike Rust or Zig, cforge allows teams to improve safety without rewriting a single line of legacy code. Just include the header and start using AUTO_FILE for new code.

2. Production-Hardening Automation

The combination of sanitizer→hardening pipeline is unique:

  # One command gets you:
  # - AddressSanitizer (development)
  # - Stack canaries (production)
  # - Control-flow integrity (production)
  # - PGO optimization (production)
  cforge pgo main.c

3. C as a "Safe Assembly"

safe_c.h demonstrates that C can be used as a portable assembly with safety guardrails, challenging the narrative that C is inherently unsafe.

4. Reflection Without Runtime Cost

The annotation→generation approach proves you can have:

────────────────────────────────────────────────────────────────────────────────

6. Limitations and Trade-offs

A. Fundamental Limitations

cforge_07

B. When NOT to Use cforge

C. The "Two-Step Build" Problem

  cforge reflect  # Generate code
  cforge build    # Compile

This is more complex than single-step compilation, though cforge automates it.

────────────────────────────────────────────────────────────────────────────────

7. Impact on C Ecosystem

A. Influencing C Standards

safe_c.h demonstrates demand for:

B. Bridging C and Modern Languages

cforge shows a migration path:

  1. Start with C + safe_c.h
  2. Add reflection annotations
  3. Generate bindings for other languages
  4. Gradually replace modules with Rust/Zig

C. Tooling Elevation

By integrating:

cforge raises the bar for what C build tools should provide.

────────────────────────────────────────────────────────────────────────────────

8. Future Implications

The "Annotated C" Pattern

The REFLECTED, JSON_KEY, VALID_RANGE annotations suggest a future where:

Build System Convergence

cforge's use of Zig for cross-compilation suggests a trend:

────────────────────────────────────────────────────────────────────────────────

Conclusion

cforge + safe_c.h contributes the "missing link" in systems programming: a way to write safer C without leaving C.

Its key contributions are:

  1. Proving C can be safe-ish with the right tooling
  2. Lowering the barrier to safety (no rewrites required)
  3. Demonstrating annotation-driven development for C
  4. Automating production hardening (PGO, sanitizers, hardening flags)
  5. Providing a migration path from C to safer languages

For the C ecosystem, this means:

The ultimate contribution: Showing that C's obsolescence is not inevitable—with the right headers and build tools, C can remain viable for new development while teams gradually migrate to Zig or Rust.

cforge with safe_c.h represents a novel "progressive enhancement" approach to modernizing C—delivering C++17/Rust-like safety and ergonomics without abandoning C's core philosophy or requiring language changes. It fills a critical gap in the C ecosystem: how to write safer C without learning a new language or accepting runtime overhead.

Some screenshots of cforge: cforge

cgrep_project_structure

cflags_targets

test_suite

Addendum

How does this cforge+safe_c.h combo affect my programming?

I'm currently using cforge+safe_c.h for a monsoonsim-lite project ~ a CLI-based business simulator. Another question I get asked frequently: will I open source the code for cforge and safe_c.h ? I'm not sure, most of the programs I've built are for internal use either me personally or office related work.

I actually don't want a "maintainer's life" as the creator of Zen-C is currently having. As mentioned earlier: I live in 2 worlds (finance and programming). I built something, it works for me and that's it. If there's a bug I'll fix it, if there's additional features that I need, I'll make the features.

The key: it revolves around to what I need and my use case, I'm not interested to what others need. So yeah it's the opposite mindset of a maintainer. Why do I have this mindset? Coz I've burned out before trying to fulfill other people's requests and I don't want to repeat that. Sorry for the rant...cheers!

Comments section here

If you enjoyed this post, click the little up arrow chevron on the bottom left of the page to help it rank in Bear's Discovery feed and if you got any questions or anything, please use the comments section.