C extensions, portability, and alternative compilers
Key takeaways
- Anyone who's written C knows that full ISO C standard-adhering code is an impractical rarity.
- I have ran into many of these situations while working on my C compiler, so here's a small list of some of them.
- The system's C library headers is the first 'obstacle' for a C compiler aspiring to be useful.
Anyone who's written C knows that full ISO C standard-adhering code is an impractical rarity. Most real world C code out there relies on non-standard behaviors and language extensions to varying extents, and a lot of this isn't for extra features, but just to work around bugs and gaps in different compilers and libraries. A lot of codebases will try somewhat to support various environments, mostly through the use of preprocessor checks and guards, but these attempts are finicky at best and straight up broken at worst.
I have ran into many of these situations while working on my C compiler, so here's a small list of some of them.
The system's C library headers is the first 'obstacle' for a C compiler aspiring to be useful. If you can't preprocess and parse <stdio.h>, you won't get past hello world. Because I use GNU/Linux, that means glibc. Now, to their credit, glibc does try to retain compatibility of its headers on non-GCC compilers. In the monstrosity that is sys/cdefs.h, which is indirectly included by every libc header, they use all kinds of preprocessor checks for compiler-predefined macros to determine what kinds of compiler extensions are supported, and #define things away when they aren't.