In the quest to ensure my C code is as portable as possible and, in particular, does not depend on any gcc extensions, I did some looking for C compilers that work on Unix-like x86 (32-bit) systems, are libre (“free as in freedom”), and support C89. Here is a list of the compilers I found that meet this definition and some of the caveats and benefits of each:
- GNU Compiler Collection (GCC) – The default compiler on libre Unix-like systems. Though the most popular compiler in this class, it compiles slowly relative to other compilers and also includes many extensions that diverge from the C89 and C99 standards, some of which are impossible to disable even through command-line switches like
-std
or-ansi
, making it difficult to tell if your code is standards-compliant. - Tiny C Compiler – A small and fast C compiler. It supports most of C99 plus some GCC extensions. Unfortunately, there doesn’t seem to be a way in the command line options to disable the GCC extensions or C99 behavior to get a C89 compiler. It works as a drop-in replacement for gcc in many cases and is available on Debian-based systems in the tcc package. It is licensed under the LGPL.
- TenDRA – C compiler with standards in mind. Supports a range of standards modes. TenDRA provides error messages that reference the section number of the C specification that was violated. It’s available on Debian-based systems in the tendra package, which contains the tendracc binary. It worked for me in a small project using
CC="tendracc -Ysystem"
. Adding-Xs
provides a plethora of checks for possibly bad code. I recommend trying different parameters for-Y
; unfortunately I could only successfully include the libpcre header with-Ysystem
. TenDRA is released under a 3 clause BSD license. - Portable C Compiler (pcc) – Based on the original Portable C Compiler by S. C. Johnson, written in the late 1970s. pcc has been added to the NetBSD and OpenBSD source trees as a possible replacement for GCC in the future. This is largely due to its simpler design and its license: mainly 2 and 3 clause BSD. There is no Debian package yet (though it has been request), but there are instructions for installation. I have not tested it myself, but I believe it is largely extension-free, making it a good test of standards compliance.
- The Amsterdam Compiler Kit (ACK) – Designed for low-end machines (such as 8086 and 80386); very fast. ACK is released under a 3 clause BSD license. It does not appear to be in the Debian repositories, but would probably be a good test for standards compliance due to its minimalistic nature.
There are a number of libre x86 C compilers for Unix-like systems that are in development, but not quite ready for production use yet:
- clang – C language front-end for LLVM. This will replace the GCC front-ends currently used by LLVM. It aims to be compatible with GCC extensions; it’s unclear how easy those will be to disable. Due to LLVM’s modular nature, it will be easily optimizable through the LLVM IR and probably much easier to understand than the GCC code base.
- Nils Weller’s C compiler (nwcc) – C90 support almost completely implemented. Includes some C99 and GCC extensions. Currently “not intended for serious use”.
There are several other C compilers out there that others may find useful, but don’t fit my requirements exactly. This is usually because the license is not sufficiently free or the target architecture is not 32-bit x86.
- Open64 – The Open Research Compiler – An x86-64 compiler used mainly for research purposes.
- Bruce’s C Compiler (bcc) – 16-bit x86 compiler. Resulting binaries do not run on a 32-bit x86 system, but can be run using elksemu. Available in Debian as bcc. Might not fully support C89; I had some problems compiling non-trivial code with it.
- Local C Compiler (lcc) – A retargetable compiler for ANSI C. Likely has very good standards support, but is released under a non-free license: “You may not sell lcc or any product derived from it”.
- Open Watcom – The Watcom compiler, popular for fast execution speed of compiled code and one of the first to support 80386 protected mode. It does not support Unix-like systems yet, though support is being added. Unfortunately, it also uses a non-free license: you may use it “solely for Your internal research and development and/or Personal Use”.
By compiling your code using several different compilers, especially those that are picky about standards, you can be more confident of its portability to other compilers. Doing so also helps future-proof your code: it will be easier to port it to new processor architectures and operating systems because the chances are good that your code will be recognized by new standards-compliant compilers.
If I missed any libre x86 C compilers for Unix-like systems, please let me know and I’ll add them to the list.
Putting tinycc above nwcc seems a bit harsh as far as correctness is concerned. nwcc may not be capable of building most large apps like gcc and Linux, but many other medium sized things work (PostgreSQL, bash, xterm, tar, wget, lynx, coreutils, findutils, cpio, bison, gxemul, strace, lsof, zsh and many other such things. Some of these, like xterm, don’t work with tinycc). Tendra is also probably much less usable than nwcc for typical open source apps.
Thanks for updating me on nwcc. My post was based largely on how the various compilers were described on their respective web sites. Since nwcc web site contains phrases like “Support for various C language features is incomplete or broken” and “The current release is not intended for serious use”, I assumed that it probably didn’t compile a lot of programs yet. Since TCC and Tendra self-reported as being fairly complete, I assumed they were.
The article was meant to provide a brief list that readers could use to guide further research. I only installed and briefly tested compilers that were available in Ubuntu’s repositories.
The intent of my post was to provide a list of compilers that would be useful in helping developers test how standards-compliant (particularly C89-compliant) their programs are. I wasn’t concerned with how many existing open source apps each compiler could compile since many of these apps are not intended to work on standard C89 compilers.
It really doesn’t bother me that nwcc can’t compile the Linux kernel since the kernel developers don’t care about any compilers other than gcc and don’t intend to ever make it C89-compliant. It’s good to know that nwcc can compile a wide range of C programs.
It would be nice if the list of programs you mentioned that nwcc can compile was listed somewhere on the nwcc web site. The way most people determine the maturity of a project is through what is reported on its web site. And nwcc’s web site reports nwcc as being immature, whereas TCC’s web site suggests TCC is fairly mature.
I appreciate your information about nwcc and I hope that some of it will make it onto the nwcc web site.
Thanks for the quick response! I agree some of these ultra defensive statements must go. C89 support is pretty complete now (can’t think of any missing things offhand – perhaps digraphs?), but there are always things which may be broken on some platforms like MIPS and SPARC. Without these disclaimers, people may expect flawlessness. However, some things could probably be phrased more positively.
C89 checking is a double-edged sword. On the one hand there is no clear separation between C89/C99/GNU C yet, and some “sensible” extensions are silently accepted. But many other extensions like sizeof(void), nonconstant array/struct initializers, or VLAs always yield a warning even though they are accepted. That’s a bit inconsistent for now.
And then there are things which are illegal in both standard C and GNU C but which are silently accepted regardless – some in const correctness, unnamed function parameters, some variable conditional operator operands, mixed declarations and code. These are bugs of course. tinycc probably has a lot more such cases, especially in typechecking – e.g. it allows void foo()()()() {} 🙂
A table of applications that work with nwcc would be nice to have. Hopefully it will appear on http://nwcc.sourceforge.net/apps.html some day.
Thanks for your feedback
The website does have such a table now: http://nwcc.sourceforge.net/apps.html
Thanks for the link! It seems nwcc is progressing well; I see that it can compile gcc now. I’ll definitely keep it in mind for checking my code’s validity.