Comprehensive comparison of three modern systems programming languages that evolve the C programming model: V (Vlang), Zig, and C3. This repository collects compiler-validated examples, a benchmark harness for example-driven performance comparison, and practical notes on trade-offs.
Quick links
- Examples: ./examples/ (12 topics, each with V, Zig, C3 variants)
- Benchmarks: ./results/bench_results.md
- Harness: ./scripts/bench_examples.sh
- Install Compilers: Ensure
v,zig, andc3care in your PATH. - Verify Setup: Run
./test_all.shto make sure all examples compile and run. - Run Benchmarks: Execute
./scripts/bench_examples.shand checkresults/bench_results.md.
Table of contents
- Overview & philosophy
- Feature comparison
- Build & run instructions
- Context performance
- Contributing & adding examples
- References
Goals
- Provide side-by-side examples across V, Zig, and C3 to compare language ergonomics and semantics.
- Produce reproducible, example-driven context performance measurements.
- Offer practical migration notes for C developers considering each language.
Requirements
- POSIX-like environment (Linux/macOS). Tested on Linux.
- Optional compilers on PATH to build language variants:
- v (V) — https://vlang.io
- zig (Zig) — https://ziglang.org
- c3c (C3) — https://c3-lang.org
- /usr/bin/time is preferred for accurate timing; otherwise the script uses a coarse fallback.
Examples layout
- examples/<NN_topic>/ contains files named .v, .zig, .c3 and sometimes prebuilt executables.
- Each directory targets the same small program or behavior (hello world, arrays, enums, etc.) so outputs and semantics are comparable.
.
├── examples/ # Side-by-side code examples (V, Zig, C3)
│ └── NN_topic/ # e.g., 01_hello_world, 06_generic_stack
├── results/ # Benchmark results and analysis
│ └── bench_results.md
├── scripts/ # Automation tools
│ └── bench_examples.sh # Performance harness
└── test_all.sh # Validation script to run all examples
Build & run (short)
To run a specific example manually, create a bin directory first: mkdir -p bin.
- V:
v -o bin/myprog examples/01_hello_world/hello.v && ./bin/myprog - Zig:
zig build-exe -O ReleaseFast -femit-bin=bin/myprog examples/01_hello_world/hello.zig && ./bin/myprog - C3:
c3c -o bin/myprog examples/01_hello_world/hello.c3 && ./bin/myprog
Notes
- Some examples rely on small inputs (examples/04_file_io/input.txt). Benchmarks discard program output when timing.
- Binaries are written to .build// by the harness. Build flags aim for release-like timings; adjust in the script if needed.
How the benchmark works
- scripts/bench_examples.sh scans each topic folder, compiles available sources (v/zig/c3) when compiler is available, runs each executable N times (default 5), averages wall-clock times, and writes results/bench_results.md.
- The harness captures failures (missing compiler, build failure) and lists prebuilt executables found in example folders.
- Caveats: wall-clock includes process startup and I/O; for microbenchmarks prefer in-language benchmarking harnesses. System noise, CPU frequency scaling, and background load affect results.
Reproducing a focused benchmark
- Install compilers and ensure they are on PATH.
- Make script executable: chmod +x ./scripts/bench_examples.sh
- Run with desired runs: ./scripts/bench_examples.sh 10
- Inspect results/bench_results.md
Adding a new example
- Create a new directory examples/NN_description/.
- Add files: description.v, description.zig, description.c3 implementing equivalent behavior.
- Optionally include small input files under that directory.
- Run the harness to include the topic in results.
Validation & tests
- Automated Validation: Run
./test_all.shto compile and run every example in the repository to ensure they still work. - Note: The harness and test script only build and time programs; they do not perform semantic equivalence checks between languages. For CI, consider adding language-specific test runners.
Contribution guidelines
- Prefer small, focused examples that demonstrate one concept per topic.
- Follow existing naming: two-digit prefix for ordering (01_hello_world) and matching basenames across languages.
- When adding new examples, include minimal README notes inside the example folder if special build steps or inputs are required.
License
- Most content in this repo follows MIT. Check individual language implementations for their own licenses.
Contact / Maintainers
- Repository: naranyala/between-v-zig-c3
- Open issues or PRs for improvements, corrected examples, or performance runs.
Reference comparisons (feature tables retained below)
| V (Vlang) | Zig | C3 | |
|---|---|---|---|
| Website | vlang.io | ziglang.org | c3-lang.org |
| GitHub | vlang/v | Codeberg | c3lang/c3c |
| Stars | 37.7k | 43.2k | 5.6k |
| Version | 0.5.1 | 0.16.0 | 0.8.1 |
| License | MIT | MIT | MIT / LGPL-3.0 |
| Creator | Alexander Medvednikov | Andrew Kelley | Christoffer Lernö |
| Written In | V (self-hosting) | Zig (self-hosting) | C (compiler) |
| Tagline | Simple, fast, safe, compiled | Robust, optimal, reusable | The ergonomic, safe, familiar evolution of C |
| Feature | V | Zig | C3 |
|---|---|---|---|
| Default GC | Yes (tracing) | No | No |
| Manual memory | -gc none |
Default | Default |
| Autofree | Experimental | N/A | N/A |
| Arena allocation | -prealloc |
Allocator pattern | N/A |
| Defer | No | defer/errdefer |
defer |
| Feature | V | Zig | C3 |
|---|---|---|---|
| Model | Option/Result | Error unions | Optionals + faults |
| Null safety | No null by default | Optional types | ? type |
| Panic-free | Partial | Yes | Yes (safe mode) |
| Stack traces | No | No (default) | Yes (debug) |
| Feature | V | Zig | C3 |
|---|---|---|---|
| Generics | Yes | Via comptime |
Generic modules |
| Compile-time exec | Limited | comptime |
Yes |
| Reflection | Limited | @typeInfo |
Compile + runtime |
| Macros | No | No (comptime) | Semantic macros |
| Operator overloading | Yes | Yes | Yes |
| Feature | V | Zig | C3 |
|---|---|---|---|
| Sum types | Yes | No | Yes (faults) |
| Tagged unions | Yes | Yes | No |
| Type inference | := |
var/const |
Limited |
| Immutability default | Yes | const |
No |
| Distinct types | No | No | typedef |
| Slices | Yes | Yes | Yes |
| SIMD vectors | No | Yes | Yes |
| Aspect | V | Zig | C3 |
|---|---|---|---|
| C ABI compatible | Yes | Yes | Yes (full) |
| C header import | Manual | Auto (@cImport) |
Module system |
| C code compilation | No | Yes (zig cc) |
No |
| C → Target translation | Yes (c2v) | No | No (planned) |
| C++ support | Limited | Yes | No |
| Memory model compat | Partial (GC) | Full (manual) | Full (manual) |
Key insight: Zig has the most mature C interop — it can compile C code directly. C3 has the purest ABI compatibility — mix C and C3 in one project with zero wrappers. V can translate entire C codebases via c2v.
| Tool | C | V | Zig | C3 |
|---|---|---|---|---|
| Valgrind | Native | Via C backend | Native | Native |
| AddressSanitizer | Native | Via C compiler | Native | Via LLVM |
| GDB/LLDB | Native | Via C output | Native | Native |
| perf | Native | Works | Works | Works |
| pkg-config | Native | Limited | Via build.zig | Via CMake |
| C Pain Point | V | Zig | C3 |
|---|---|---|---|
| Header hell | Solved (modules) | Solved (imports) | Solved (modules) |
| Preprocessor | Eliminated | Eliminated (comptime) | Replaced (semantic) |
| Null bugs | Eliminated (optionals) | Mitigated | Mitigated (?) |
| Buffer overflows | Solved (bounds check) | Solved (bounds check) | Solved (safe mode) |
| Manual memory | Partial (GC default) | Explicit (allocator) | Explicit (manual) |
| Undefined behavior | Mostly eliminated | Mostly eliminated | Partially (safe mode) |
| No build system | Solved (built-in) | Solved (zig build) |
No (CMake) |
| No package manager | Solved (vpm) | Partial | No |
| Verbose error handling | Solved | Solved (comptime) | Solved (optionals/faults) |
| No generics | Solved | Solved (comptime) | Solved (generic modules) |
| No cross-compilation | Solved (easy) | Solved (excellent) | Basic |
| No testing | Solved (built-in) | Solved (built-in) | Solved (built-in) |
| No defer | No | Yes | Yes |
| No contracts | No | No | Yes |
| No reflection | Limited | Yes (comptime) | Yes (compile+runtime) |
- Simplicity — Learnable in a weekend, only one way to do things
- No undefined behavior — Bounds checking, no null, no variable shadowing
- Immutability default — Variables/structs immutable unless marked
mut - Fast compilation — Self-compiles in <1 second
- C as backbone — Compiles to human-readable C
- Minimal dependencies — Single binary, no build environments
- Flexible memory — GC, autofree, manual, or arena
- No hidden control flow — No exceptions, hidden allocations, implicit casts
- No hidden memory — Every allocation explicit via allocator parameter
- No preprocessor/macros —
comptimereplaces both - Robustness over performance — Debug checks everything; release optimizes
- Incremental improvement — Add Zig to C/C++ projects one file at a time
- Cross-compilation first — Targets every platform from any platform
- Reader-oriented — Code optimized for reading, not writing
- Evolution, not revolution — Stay close to C, change only what's necessary
- C ABI compatibility — Mix C and C3 with zero friction
- Procedural mindset — "Get things done" language, not academic
- Familiarity — Minimal learning curve for C programmers
- Data is inert — Avoid "big ideas" and "more is better" fallacy
- Safety where it matters — Runtime checks in debug, contracts for pre/post
- No header files — Module system replaces
#include
| Pros | Cons |
|---|---|
| Simplest syntax (learnable weekend) | Pre-1.0, APIs may change |
| Fastest compilation (~400k loc/s) | Autofree experimental |
| Built-in web/GUI/ORM/JSON | GC overhead (must opt-out) |
| C translation (c2v) | Limited metaprogramming |
| Hot code reloading | Smaller ecosystem than C |
| REPL for scripting | Less low-level control |
| Cross-compilation via flags | C backend dependency |
| Pros | Cons |
|---|---|
| Comptime power | Steep learning curve |
| Best cross-compilation | Verbose syntax |
| Drop-in C/C++ compiler | No package manager (centralized) |
| Explicit allocators | No built-in web/GUI |
| Robust error handling | Slower compilation |
| Production adoption (Bun, TigerBeetle) | No GC option |
| ZSF non-profit governance | Unstable API |
| Pros | Cons |
|---|---|
| Full C ABI compatibility | Smallest community |
| Familiar C syntax | Not self-hosted |
| No header files (modules) | No package manager |
| Semantic macros | Limited ecosystem |
| Generic modules | No built-in web/GUI |
| Contracts (pre/post conditions) | CMake build system |
| Detailed stack traces (debug) | No cross-compilation from non-native |
| Scenario | C | V | Zig | C3 |
|---|---|---|---|---|
| CPU-bound | 100% | ~95-100% | ~100% | ~100% |
| Memory-heavy | 100% | ~80-90% (GC) | ~100% | ~100% |
| I/O bound | 100% | ~95% | ~100% | ~100% |
| Compilation speed | Baseline | Much faster | Slower (comptime) | Moderate |
When C still wins: Startup time, minimal binary size, embedded systems, legacy hardware, extreme optimization.
When V/Zig/C3 match C: With -O3, manual memory (V: -gc none, Zig/C3: default), proper compiler flags.
| Language | Notable Projects | Domain |
|---|---|---|
| V | Volt (Slack client), Ved (editor), Vinix (OS) | Desktop, editor, OS |
| Zig | Bun (JS runtime), TigerBeetle (DB), Mach Engine | Runtime, database, game engine |
| C3 | vkQuake (partial port) | Game engine |
| Aspect | C → V | C → Zig | C → C3 |
|---|---|---|---|
| Syntax changes | High (Go-like) | High (unique) | Low (C-like) |
| Memory model | High (GC) | Medium (allocators) | Low (same) |
| Error handling | High (option/result) | High (error unions) | Medium (optionals) |
| Build system | High (new) | High (new) | Low (CMake) |
| Library reuse | Medium (c2v) | High (@cImport) | High (extern) |
| Time to productivity | Days | Weeks | Hours |
| Use Case | Recommended | Why |
|---|---|---|
| New project, no C legacy | V or Zig | V for simplicity, Zig for power |
| Existing C codebase | C3 or Zig | C3 for minimal changes, Zig for tooling |
| Web application | V | Built-in web framework |
| Game engine | Zig or C3 | Zig for tooling, C3 for C compat |
| Operating system | Zig | Best cross-compilation, explicit memory |
| Library for C consumers | C3 | Purest C ABI compatibility |
| Prototyping | V | Fastest compilation, simplest syntax |
| Production system | Zig or C | Zig for modern features, C for maturity |
| V | Zig | C3 | |
|---|---|---|---|
| Learning Curve | Easy | Moderate | Easy (for C devs) |
| Syntax Style | Go-like | Unique | C-like |
| Best For | General purpose, web, prototyping | Systems, OS, cross-compilation | C replacement, incremental migration |
| Key Strength | Simplicity + speed | Comptime + tooling | C compatibility + familiarity |
| Biggest Weakness | Pre-1.0, less low-level | Steep learning curve | Small community |
| FFI Quality | Good | Excellent | Excellent (purest C compat) |
| Memory Safety | GC + optional manual | Manual only | Manual only |
| Production Ready | Emerging | Emerging | Emerging |
This repository includes a small benchmark harness that builds (when compilers are available) and runs the examples in ./examples to compare runtime (wall-clock) between V, Zig, and C3. Results are written to results/bench_results.md.
To run the benchmark:
-
Ensure compilers/tools are installed and on PATH:
v(V),zig(Zig),c3c(C3). If a compiler is missing, the script will skip that language and will attempt to run any prebuilt binaries found in each example directory. -
Run:
./scripts/bench_examples.sh [runs]
where
[runs](optional) is the number of runs to average (default: 5). Example:./scripts/bench_examples.sh 5
-
View results:
results/bench_results.md
Sample output is written to results/bench_results.md when available. The script is safe to run repeatedly; build artifacts are written to .build/.
- Comparison of programming languages
- Systems programming language
- Memory management
- Garbage collection (computer science)
- Manual memory management
- Undefined behavior
- Error handling
- Option type (nullable/optional)
- Algebraic data type
- Discriminated union
- Generics (generic programming)
- Type inference
- Reflection (computer science)
- Metaprogramming
- Design by contract
- Concurrency (computer science)
- Null safety
- Foreign function interface
- Application binary interface
- Cross-compilation
- Package manager (software)
- REPL
- Hot swapping (hot code reloading)
- Stack trace
- SIMD
- C (programming language)
- Zig (programming language)
- V (programming language)
Last updated: July 2026