# madc
**A self-contained C and C++ compiler — JIT, AOT and an interactive REPL in
one small download.**
madc compiles standard C (C89 through C23) and C++ (C++98 through C++20) with
its own front end and its own code generator. It runs a program straight from
source, in memory; writes native objects and executables; emits portable C11;
and opens an interactive REPL. It needs no GCC, Clang or LLVM, no linker, and
no headers on disk: the C, POSIX and C++ standard-library headers ship inside
madc.
madc is not a new language wearing C's syntax. It compiles the C and C++ you
already have — and, as one more `--std=`, offers its own dialect for code that
wants less ceremony.
[Install](#install) · [Usage](docs/usage.md) · [Benchmarks](docs/benchmarks/README.md) ·
[Conformance](docs/conformance-coverage.md) · [Changelog](CHANGELOG.md) ·
[Security](SECURITY.md)

*The REPL: C++ typed in; a function copied and renamed with ex commands
(`:t`, `:s`); both versions called; then `??world` and `?say_hello` ask the
session what it knows.*
## One compiler, every way to run code
Ordinary C++, nothing madc-specific:
```cpp
#include
#include
int main()
{
std::string who = "world";
std::cout << "Hello, " << who << "!\n";
}
```
```bash
madc hello.cpp # compile in memory and run it (JIT)
madc -o hello hello.cpp # a native executable (AOT)
madc -c hello.cpp # an object file — g++ and clang++ link it
madc --emit=c11 hello.cpp # the same program as portable C11 source
madc # the REPL
```
- **JIT.** `madc file.cpp` compiles into memory and runs — usually before
g++ or clang++ would have finished linking (see [Speed](#speed)). A
`#!/usr/bin/env madc` line makes a source file an executable script.
- **AOT.** `-o` writes the executable itself; there is no linker to call. On
Linux a C hello-world is a 10 KB executable that needs only the C library,
and the C++ one above is 22 KB and needs only the C and C++ runtime
libraries — not madc. Windows matches for C++ (a C program calling
`printf` still needs libmadc there); on macOS a C program needs only
libSystem, and C++ still needs libmadc. `-c` objects use the Itanium C++
ABI and real mangled names, so they link with g++- and clang++-built code.
- **C11 out.** `--emit=c11` renders any program, C++ included, as strict
C11 that any C compiler accepts.
- **REPL.** `madc` with no file is an interactive C and C++ session:
declarations and statements as you type them, named results, `?name` and
`??name` to look things up, `%whos`, history and completion, syntax
colour, and an ex-style editor (`:p`, `:s`, `:t`, `:w`) over the
session's own buffer — an edited function is redefined at once.
- **Projects.** `--project compile_commands.json` compiles, links and runs a
multi-file program, or writes one executable. The flagship case is SMAUG
1.8: about 158,000 lines of C89 in 51 translation units, run both ways.
## Self-contained
| madc does not need | because |
|---|---|
| GCC, Clang or LLVM | its own front end lowers to an IR that its own copy of [MIR](#built-on-mir) compiles for x86-64 and ARM64 |
| a linker | it writes ELF, PE and Mach-O objects and executables itself |
| system headers | the C library, POSIX and C++ standard-library headers are built into madc |
What it does use is the platform's own runtime: the C library and one C++
standard library — libstdc++ on Linux and Windows, libc++ on macOS, where it
is part of the OS. On Linux it also uses the system's zlib, zstd and PCRE2;
the Windows zip carries the DLLs it needs.
| Platform | Packages | Download |
|---|---|---:|
| Linux x86-64 | `.deb` (Ubuntu 22.04, 24.04), `.rpm`, tarball | 18–21 MB |
| Windows x86-64 | zip | 19 MB |
| macOS (Apple silicon, Intel) | tarball | 18 MB |
## Built on MIR
One large third-party component makes this possible:
[MIR](https://github.com/vnmakarov/mir), Vladimir Makarov's lightweight JIT
compiler infrastructure, and c2mir, its C11 compiler (MIT licence).
The division is clean. madc's front end reads C, C++ and the dialect,
resolves classes, templates and overloads, and builds c2mir's own C11 syntax
tree directly — c2mir never sees source text. c2mir checks that tree and
lowers it to MIR; MIR's generator turns it into machine code, in memory for
the JIT or as a native object.
madc carries its own maintained copy of MIR in
[`third_party/mir`](third_party/mir) — a git subtree with upstream history
kept, built and released with madc. To upstream MIR it adds:
- native **object and executable writers** — ELF, PE/COFF and Mach-O;
- C language features: native `_Complex`, `__attribute__((cleanup))`,
vector types up to 16 bytes, and `volatile` accesses that every
optimization pass respects;
- ABI and code-generation fixes for variadic calls, `_Complex`, `_Alignas`
and ARM64.
Fixes that belong to MIR itself are offered upstream as pull requests.
## Speed
madc 0.106.0 against g++ 13.3 and clang++ 18.1 on the same machine
(Ubuntu 24.04, x86-64), in milliseconds, best of 7 runs, interleaved —
lower is better:
| task | madc | g++ / gcc | clang++ / clang |
|---|---:|---:|---:|
| `hello.cpp` (``), source to output | **81** | 186 | 213 |
| `` + `