It was less than a year ago that I wrote about linker hacking the
runtime out of D code so that it could work as “better C” code, but things have already changed a lot since
then. A few days ago Walter Bright announced a new,
-betterC switch, which can now do a lot of the stuff that needed ugly hacking
-betterC, and Why do I Need it?
The short answer is that most D programmers don’t need it. The longer answer is that it does two things: first, it restricts the language to a lower-level subset (that’s still higher-level than C), and, second, it changes the implementation of compiled code a little so that it only depends on the C runtime, and not the D runtime.
If you just want control over things like GC and runtime features for performance reasons, you can already get
-betterC. You can read more about that in this GC series on the official blog, and in my previous post about the D runtime itself.
-betterC does provide is an intermediate language that integrates very well with
both C code and D code. Walter envisions this as a way for D to penetrate more into parts of the software world
that are still dominated by C. For example, practically all languages today still run on top of a layer of
operating system libraries that are written in C (and C++ in the Windows world). D’s runtime itself depends on
this layer, so D can’t ever replace C unless runtimeless programming is possible.
-betterC switch is a little controversial, and I agree that things could be better in the
-betterC is here today, and ultimately we’re only going to figure out how to use D as a
better C by trying it out. That’s why I originally published that post about runtimeless D, even though it was a
There are two main ways betterC programming has improved since I last wrote about it. One pain point was the
over-dependence on runtime reflection in the language implementation, even for things like integer array
comparisons that could be implemented with just
memcmp(). A lot of work has been done since then to
replace reflection with templates, which is good news even for programmers who aren’t doing low-level stuff.
Lucia Cojocaru presented some of this work at DConf
The other area of improvement is in the
-betterC switch itself. Back then there were only two
places in the DMD compiler where
-betterC had any effect at all, so most runtime dependencies were
left in. Simply defining a struct, for example, would still cause the D compiler to insert
instances for runtime type information, which depend on base class implementations that are defined in the D
assert statements would still be implemented using a D runtime implementation, not
the C runtime implementation. These are the two most obvious problems that have been fixed.
-betterC Take Two
In that old post, I took some D code, compiled it, hacked out the runtime, and then linked it directly to some C code without the D runtime. Let’s see how things work now. Here’s the D code again:
And here’s the C code:
Here’s what happens now (on a GNU/Linux system):
Damn. So close. The D compiler has left in some exception handling data structures, even though
-betterC isn’t supposed to support exceptions. You’ll see I’m using the new DMD beta, and there’s
already an open bug report and pull request for this
kind of problem, so I expect it’ll be fixed soon. I’ll update this post when it is.
Here’s a quick workaround for now (read the original linker hacking article for an explanation):
It might not look like much, but it’s a huge improvement. Thanks to all the developers who helped make it happen.