4 ms·
Professional compiler engineer here, C is a mediocre intermediate language. Let's start with an excellent quote from Wittgenstein. "The limits of my language m
by cokernel_hacker 10y ago
Professional compiler engineer here, C is a mediocre intermediate language.
Let's start with an excellent quote from Wittgenstein.
"The limits of my language mean the limits of my world."
Using C as your intermediate language means that your expressiveness is limited to valid C programs. This is workable but only if your language can be mapped to C in _useful_ ways.
For example, let's say your language has behavior similar to scheme's tail-call.
How would you get this behavior from a C compiler? You will never be able to make this reliably across optimization levels, etc.
Guaranteed tail-calls are the tip of the iceberg, there are a lot more features which cannot be reasonably mapped onto C.
Real compiler IRs increase your expressivity beyond what the C language designers decided was important.
- pcwalton 10y agoExactly, and this is what most people who work on compilers discovered long ago. It's disappointing to see "just compile to C!" still so popular on HN. I would cite GC as the most prominent example of a feature that is incompatible with compiling to C. It is impossible to write a competitive high performance tracing GC on top of C. Mandatory register spills at safe points and conservative scanning have huge downsides.
- ndesaulniers 10y ago> It's disappointing to see "just compile to C!" still so popular on HN. Posts on C get blindly upvoted on HN and proggit. I guarantee it. Me thinks it's like the history channel for programmers; learning about their forerunners and how they had to bang rocks together to make fire. It's also how I've gotten all of my karma. Unfortunately, the abyss has also looked into me, as I now write C code for a living...
- groovy2shoes 10y agoUsing C as an intermediary language can still be useful at times. For example, when writing a bootstrap compiler, you can target C and magically support virtually every platform. It's not so great for production compilers for numerous reasons, including performance (poor unless your languages maps cleanly to C) and debugging experience (debugging object code is not fun, and if your object is C, you get stuck with whatever debugging information your C compiler outputs; you don't have any say in the matter). For bootstrapping compilers, I only see three sane options, really: 1. Write an interpreter to host the compiler (probably in C). 2. Write a cross-compiler. 3. Write an X-to-C compiler. I insist on C here not because of performance, but because it's ubiquitous.
- loup-vaillant 10y ago> For example, let's say your language has behavior similar to scheme's tail-call. How would you get this behavior from a C compiler? Well, there's still the unreasonable way: compile in continuation passing style, and trampoline every call. I shall not be held responsible for any performance problem this advice may cause however…