fcc

A fast C compiler written in pure V, aimed at replacing the bundled TinyCC that vlang/v uses as its default C backend on Windows.

build MIT

Status

Phase 2 is done: the compiler translates whole C programs to x86-64 assembly through a real Windows x64 ABI — variadic calls, callee-saved registers, stack probes for frames over a page, struct returns, bitfields, and floating point.

SuiteResult
Differential end-to-end (tests/endtoend/)20 of 20 match tcc/gcc
c-testsuite single-exec (220 cases)208 match, 12 differ with tcc control each
chibicc suite9 of 18 (9 are host-ABI divergences, not defects)
Unit tests (v test .)10 of 10

Every differ carries its tcc oracle control, so a defect in fcc is distinguished from a gap tcc shares. Open items and their reproducers live in docs/PLAN.md.

Diagnostics

Errors keep the terse tcc: first line the V driver keys on, followed by a source block with file, line, column, a caret span, and = help: hints where the fix is known:

tcc: foo.c:12:9: expected ";", found "bar"
 --> foo.c:12:9
  |
12 | int x = 5  bar = 6;
  |              ^^^
  |
  = help: a declaration or statement ends with `;` — one is missing before this token

Quick start

Prerequisites: the V toolchain plus a checkout of it (fcc takes its oracle tcc and its linker gcc from there).

$env:VCC_V_ROOT = 'C:\path\to\v'
$env:TMPDIR = "$env:LOCALAPPDATA\Temp\opencode\vccbuild"
v -o fcc.exe .
v test .
$env:VCC_PROBE_DIR = "$env:LOCALAPPDATA\Temp\opencode\va-probe"
v run tools/probe/probe.v     # differential programs vs tcc/gcc

Design in one paragraph

The code generator sits behind a swappable backend interface. Phase 2 emits text assembly validated against three independent oracles; a future phase swaps in a machine-code emitter behind the same interface. The front end is written once. Nothing is trusted without a cross-boundary test: a calling convention or data layout that is wrong in a way two fcc-compiled functions agree on is invisible to any test that never leaves the compiler.

Links