Ah, okay. I thought/assumed this was about code running on a microcontroller or similar embedded and constrained devices.
I can see why the folks here would assume that it's about microcontroller / embedded systems but (as we all know) C has more applications than just embedded.
No, we assume that because of the topic at hand, not in general.
I personally use C a lot in a fully hosted environment, for both systems programming (services like nginx or apache), and heavy-duty-computing and low-level I/O parts in desktop/GUI applications.
My preferred GUI application development is to have all heavy work done in C, but the user interface written in Python, so that end users can tweak the user interface without a development environment, even if the application innards are proprietary Secret Sauce. (I develop code under various different licenses, from public domain to copyleft to completely proprietary: Tux is my mascot, not my idol. I do prefer free/open source, because I'm more productive there myself, but I am not ideologically against proprietary-licensed code either. I've even signed (sensible) NDAs.)
I have the same viewpoint as you, it's almost impossible to ditch the "old" C "standard library" - something else has to replace it with a completely new interface. But then you might as well create a new language with a similar or same syntax as C.
This is where our opinions diverge. In my opinion, the C compiler is adequate, simply based on the amount of
good C code out there. The fact that there are vast amounts of not-so-good and downright horrible code has more to do with popularity and historical baggage than the C language properties itself.
Therefore, it seems to me to start from scratch would be to 'throw the baby out with the bathwater', as the saying goes.
Indeed, as I mentioned, I have been investigating exactly what would be better than existing GNU/POSIX C library in Linux, as crazy as it might be.
It is utterly different to what I think would be better than avr-libc/newlibc in microcontrollers (which I have also been investigating on and off, separately).
Yet, the base C language suffices for both for me. (Well, I
would like one addition/change: make arrays instead of pointers the base type, with a few attendant changes, all backwards-compatible, so that for code using such buffer underruns and overruns and other memory reference bugs would be caught at compile time. The C compilers already do this, but we need some additions to help pass array size information across function call boundaries at compile time –– this does not add runtime data or new or hidden parameters to function calls, it is all about compile time.)
If GCC c++ were to grow clang-like support for named address spaces, then I would actually prefer a subset of c++ in AVR-class microcontrollers.
On Cortex-M's, my example code snippets tend to be in C because it is the lowest common denominator, but for my own code, I use the freestanding C/C++ mix I mentioned in a previous message.
Many disagree exactly which subset of C++ is appropriate on Cortex-M's and similar, and most disregard the effects of that subset on the library implementation and runtime requirements, which is why I tend to not participate in such discussions. I even see C++ embedded developers wishing for exception support... I tend to use templates, class encapsulation, class inheritance for common features like output formatting and input parsing, and function overloading, only, because that seems to be about the right balance for me, without requiring any runtime support (like stack unwinding for exceptions).
I would be surprised to learn that a MCU platform would support POSIX
newlib does contain most of POSIX C interfaces, and avr-libc
says "Some additions have been inspired by other standards like IEEE Std 1003.1-1988 ("POSIX.1"), while other extensions are purely AVR-specific (like the entire program-space string interface)."For example, both provide
strdup(),
memccpy() (note extra C, this copy stops when a specific separator byte is found), and even GNU
memmem() (finds a specific byte sequence in a specified memory range, similar to
strstr()).
Yet, because POSIX C is specifically System Interfaces, supporting it fully in a freestanding environment is not possible – there is no 'system' to interface to.
(For those who are unaware, POSIX C features are included in the standard C library on systems that do support them. In some, like Linux, you do need to define
feature test macros before including any header files, to expose the "extra" features, though. In Linux,
#define _POSIX_C_SOURCE 200809L currently exposes all POSIX.1 C features. It is important to realize that this does not cause anything extra to be loaded into memory at run time, or any extra overhead of any kind; it just changes which of the features in the base C library are exposed at compile time.)