Skip to content

Modern Features

Derek Snider edited this page May 19, 2026 · 1 revision

Modern Features

madc extends C with modern language features borrowed from Go, C++11, and others.

:= short declaration

Type inference from the right-hand side:

x := 42;              // int
name := "hello";      // string
pi := 3.14159;        // double

Also works with multiple return values:

q, r := divmod(17, 5);

auto keyword

Type inference for function pointers and lambdas:

auto fn = my_function;     // function pointer
auto add = [int](int a, int b) { return a + b; };   // lambda

defer

Go-style deferred execution — runs at scope exit in LIFO order:

ofstream out;
string fname = "output.txt";
out.open(fname);
defer out.close();         // runs at scope exit
out << "data" << endl;     // runs before the deferred close

Multiple defers execute in reverse order:

defer cout << "third" << endl;
defer cout << "second" << endl;
cout << "first" << endl;
// output: first, second, third

Lambdas

Anonymous inline functions with explicit return types:

auto print = [](string s) { cout << s << endl; };
auto add = [int](int a, int b) { return a + b; };

print("hello");
int result = add(10, 20);    // 30

Return type goes inside []: [int], [string], or [] for void.

See Functions for more.

Function pointers

void greet(string name) {
    cout << "Hi " << name << endl;
}

int main() {
    auto fn = greet;
    fn("World");
    return 0;
}

See Functions for more.

Multiple return values

Go-style:

int divmod(int a, int b) {
    return a / b, a % b;
}

q, r := divmod(17, 5);

See Functions for more.

Range-based for

C++ style iteration over arrays:

array names;
php::array_push(names, "Alice");
php::array_push(names, "Bob");

for (string name : names) {
    cout << name << endl;
}

// also works with integers
array nums;
php::array_push_int(nums, 10);
php::array_push_int(nums, 20);
for (int n : nums) {
    cout << n << endl;
}

register keyword

Declare a variable as register-only — lives entirely in a CPU register, never written to memory:

register int x = 0;
register double d = 0;

rust::match

A no-fall-through alternative to switch. See Control Flow.

prefer directive

Change namespace lookup order for unqualified names. See Namespaces.

What's next?

Clone this wiki locally