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.
↫ lemon/Sofia
Sometimes I wonder how computers even get anything done at all.

Looking at the blog post, it not the compilers that are at fault, but the library writers detecting any required features. And it is an issue as old as time.
They proxy testing for specific compilers and versions for testing for existence of features.
Just from the tip: __attribute__((packed)) is required for a Linux syscall. But only way to support it in glibc is being this this very specific list: defined __GNUC__ || defined __clang__ || defined __TINYC__. Which means, compilers have 3 options:
1 – “Fake” one of these tags, but then have to match idiosyncrasies of that particular compiler
2 – “Monkey patch” GLIBC headers while parsing them, adding brittle changes for these specific regions
3 – Accept they won’t be able to support printf(“Hello world\n”) on glibc
The actual solution would be library owners using ac-config (configure) or similar mechanisms to test for features, which would not only overcome these limitations, but also make the code simpler (have you seen the auto detection headers in those libs? The article also mentions that)
This is expected for any compiler + low level framework code. They are the ones after all that hide the cross-platform complexity. But it is good to see a compiler writer (albeit a smaller one) calling this out.
Btw, according to Google, the following now exists in the standard:
__has_attribute(),
__has_builtin(),
__has_feature()
So, they did not even need those. This is not entirely on glibc.
It just shows the fragmentation of C “standard” because it lacks of many obvious features, yet integrating other languages tweaks and functionalities to “stay relevant”. It took C23 to define officially what true and false should be, until then it was a “define” up to the coders’ interpretation.
I guess the best way ti the compiler to provide its own headers and libraries to ensure perfect integration.