C, LibC, POSIX: A Tower of Crap (WIP)
Published on 2026-10-25.
Introduction
Wouldn’t it be nice to be able to write (and run) code without being held hostage to the insane shit C people cooked up 50 years ago?
- C making it as hard as possible for anything non-C to exist on systems like Linux.
- There is no actual “interop” on these systems, just “pretending to be C” sufficiently hard enough for things to work.
- C-adjacent ecosystem throwing random unnecessary crap at people to reel them back into using C.
- It’s not a problem for C people, because it keeps their language relevant long after its expiry date.
- Everyone suffers from C people being happily stuck in the 70ies.
C
- Usual well-known problems when trying to rewrite reliable and secure software in C.
- Swaths of reserved names whose accidental use leads straight to undefined behavior.1
- LLVM hides important parts for implementing OSes’ calling conventions in the C frontend,
secret handshake between that code and the backend to emit ABI-conforming code.
Discovering this fact has become a rite of passage for every new language that uses LLVM.2 - No way for other languages to understand the ABI C provides without shipping with half a C compiler.34
LibC
- Bundles many badly designed ideas from wildly disparate use-cases into functions with random 6-letter combinations:5
- Wrappers around syscalls (but not all of them), usually making the API worse in the process.
- Functions that would be considered part of a “standard library” in other languages.
- Random assortment of features like calendar/timezone functionality, Unicode operations.
- Only way to access syscalls on some BSDs, recommended way to access syscalls on macOS:
Introducing C requirements into stacks that neither need nor want to use C. - Proprietary mechanisms like
errnothat are not accessible to non-C software, and introduce additional requirements like TLS setup.6
POSIX
- Adds wildly unsafe/complex/unimplementable functionality like
wordexp.78 and other random features (like two regex implementations) to LibC. - POSIX definitions are spooky action at a distance: Not ABI, not even API, just
“if you had a C compiler and that C compiler saw an identifier called ‘x’ in a C source file, imagine it would behave as-if …” - Not even ABI names are specified: C compiler required to figure out what’s the actual binary name of a function defined in POSIX spec.
Conclusion
- …