I used to do `if (errno) goto err;` a lot. I eventually realized that nested functions did the job much nicer:
void err() { printf("oops, we failed"); }
...
if (errno) return err();
This cleaned up a lot of my code. (The optimizer would of course inline the function, and the common tail merging would automatically convert it to the goto version in the optimizer. So this was cost-free.)
Why C doesn't officially have nested functions is, well, that's C!
Cleanup goto-style is hard to describe as a "rat's nest", since all the gotos in the same function go to the same label at the end that just does all the cleanup before returning. There's nothing clever about it, and many codebases wrap it into macros and such to make the syntax more concise and the intent explicit.
In general, any random C compiler is likely to not support that feature, because the way it interacts with function pointers makes it unnecessarily complicated.
As for function pointers, a simple solution is to not allow them unless the function is declared `static`. `static` functions don't have a hidden static link.
The problem isn't doing it as such; ALGOL 60 could do nested functions just fine.
The problem is doing it in an ABI-compatible way when you already have an ABI. The gcc implementation of nested functions does that - they are compatible with regular function pointers - but at the cost of requiring executable stack on at least some platforms.
And for C compilers that aren't gcc, the question becomes: why partially implement a non-standard gcc feature?
(That was sarcasm, FYI. Obviously it's 2023 and nobody wants to do manual function calling boilerplate as if you're programming 1960's assembly.)