The C3 Programming Language

The Ergonomic, Safe and Familiar Evolution of C

module hello;
import std::io;

fn void main()
{
    io::printn("Hello, World!");
}
import std::io;

faultdef DIVISION_BY_ZERO;

fn int? divide_int(int x, int y)
{
    if (!y) return DIVISION_BY_ZERO~;
    return x / y;
}

fn void main()
{
    int a = 4;
    int b = 0;
    int? x = divide_int(a, b);
    // int y = x * 2 this would be an error here

    if (catch err = x)
    {
        // Running if b == 0
        io::printfn("Had error: '%s'.", err);
        return;
    }
    // x is a normal "int" now,
    // so this works:
    int y = x * 2;
}
macro print_fields($Type)
{
    $foreach $field : $Type::members:
        io::printfn("Field %s, offset: %s, size: %s",
                $field::name, $field::offset, $field::size);
    $endforeach
}

fn void main() { print_fields(Foo); }
struct Stack <Type>
{
    usz capacity;
    usz size;
    Type* elems;
}

fn void Stack.push(Stack* this, Type element)
{
    // ... implementation
    this.elems[this.size++] = element;
}
import std::io;

alias MyInt = int;
typedef MyId = int;

fn void main()
{
    MyInt x = 27;
    MyId y = 3;
    int a = x;
    // int b = y; <- This doesn't work

    // Explicit conversion works
    x += (int)y;

    io::printfn("%s %s", y, x);
}

Full C ABI Compatibility

C3 fits right into your C/C++ application with full C ABI compatibility out of the box: no need for special "C compatible" types or functions, no limitations on what C3 features you can use from C.

Module System

A simple and straightforward module system that doesn't get in the way, with defaults that make sense.

Operator Overloading

C3 empowers you with precise, purpose-built operator overloading — no C++ baggage, just clean, expressive code. Ideal for vectors, matrices, and fixed-point math that reads exactly how it should.

C3 is an evolution, not a revolution: the C-like for programmers who like C.

C3 is a programming language that builds on the syntax and semantics of the C language, with the goal of evolving it while still retaining familiarity for C programmers.

Thanks to full ABI compatibility with C, it's possible to mix C and C3 in the same project with no effort. As a demonstration, vkQuake was compiled with a small portion of the code converted to C3 and compiled with the c3c compiler.


Compile Time and Semantic Macros

Unlock the full power of compile-time code with macros that read like functions — clearer, stronger, and miles beyond C's preprocessor.

Runtime and compile-time reflection

Type introspection available both at compile time and runtime, powering flexible macros and functions.

Gradual Contracts

C3 brings programming-by-contract to the mainstream with unobtrusive contracts that are used to express both runtime and compile-time constraints.

Inline Assembly

Write asm as regular inline code without using strings or cryptic constraints.

Zero Overhead Errors

Error handling that combines the best parts of "Result" errors with the easy use of exceptions and integrates seamlessly with C.

Debug with safety checks

Feel confident in your code's correctness: in debug mode the compiler inserts extensive runtime bounds checks and value checks, which together with contracts will let you catch bugs early.

Generic modules

C3 generic modules offer superior simplicity and clarity for creating generic types.

Detailed stacktraces

No more anonymous "segmentation fault" errors: the C3 standard library enables detailed stacktraces out of the box for your debug builds.