I tested the D language and zig language recently to check the state of the tooling.

D lang home

Zig home

Dlang

gdc (the gcc D compiler) is in apt, I install it with:

apt-get install gdc

I wrote a D program (example source code from dlang.org):

vi e.d
void main()
{
    import std.exception, std.stdio, std.process;

    auto result = ["whoami"].execute;
    enforce(result.status == 0);
    result.output.write;
}

Then compile the source code with gdc, -g is for the debug symbols:

gdc -g e.d -o e

Debug the e D program with gdb:

gdb -tui e
b main
r

After the r(run) command, gdb stopped in a D class calling main. s(step) ran the main function and I couldn't step in the code above (e.d). Support for debugging in gdb is not 100%.

Code coverage is enabled like this:

gdc -fprofile-arcs -ftest-coverage -g e.d -o e
./e
gcov -b e.d

It works fine.

  • D is a large language with many features
  • The garbage collector is enabled by default and optionally disabled
  • Borrow checker is optional
  • There is a system for running tests
  • Most of the SEI CERT C rules are fixed but it is optional

The learning curve is not steep, one can be productive in a short time.

Zig lang

Zig is a C-like language with less footguns than C.

I install zig by downloading a tar file from zig website:

Zig download

Extract with:

tar -xf zig-linux-x86_64-0.12.0-dev.1835+697b8f7d2.tar.xz

Add zig directory to $PATH:

export PATH=$PATH:~/zig-linux-x86_64-0.12.0-dev.1835+697b8f7d2

Create a compile zig program (from examples on zig homepage):

vi z.zig
const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    var i: usize = 1;
    while (i <= 16) : (i += 1) {
        if (i % 15 == 0) {
            try stdout.writeAll("ZiggZagg\n");
        } else if (i % 3 == 0) {
            try stdout.writeAll("Zigg\n");
        } else if (i % 5 == 0) {
            try stdout.writeAll("Zagg\n");
        } else {
            try stdout.print("{d}\n", .{i});
        }
    }
}


zig build-exe z.zig

gdb can't read the debug symbols from zig programs, so zig programs can't be debugged in gdb.

lldb supports zig, so I install it with apt:

apt-get install lldb
After this operation, 708 MB of additional disk space will be used.

708MB for a debugger, it is a lot.

Debug zig programs with lldb:

# lldb z
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'lldb.embedded_interpreter'
(lldb) target create "z"
Current executable set to '/home/me/zig/z' (x86_64).
(lldb) b main
Breakpoint 1: where = z`z.main + 12 at z.zig:4:36, address = 0x000000000021d35c
(lldb) r
Process 23773 launched: '/home/me/zig/z' (x86_64)
Process 23773 stopped
* thread #1, name = 'z', stop reason = breakpoint 1.1
    frame #0: 0x000000000021d35c z`z.main at z.zig:4:36
   1    const std = @import("std");
   2
   3    pub fn main() !void {
-> 4        const stdout = std.io.getStdOut().writer();
   5        var i: usize = 1;
   6        while (i <= 16) : (i += 1) {
   7            if (i % 15 == 0) {
(lldb)

I have been looking for a code coverage tool and I only found hacks. There is no simple way to know if the tests cover enough code or not.

  • Zig code is readable
  • Small language, fast to learn
  • Manual memory management
  • There is a system for running tests
  • Not all SEI CERT C rules are fixed, for example use after free type of errors are possible.

Hashtag: #programming #dlang #zig