What do you mean by a hosted environment?
I'm using the term as defined by the C standard. See e.g.
C99 (PDF).
Basically, when you write code to run on a machine with an operating system that provides an implementation of the standard C library, you are using a hosted environment. When you write code to run on bare metal, without the standard C library, you are using a freestanding environment.
C has little use outside kernels, microcontrollers, implementing other programming environments and writing some snippets to optimize fragments that do not perform well enough. Sure, I know there are many people who still try, but that doesn’t mean it has any sense. C is not suitable for that purpose in 2019.
Your opinion does not match reality.
Most libraries are written in C, because that way the set of dependencies is minimized. Some do use C++, but that poses several difficult to solve issues, because of the memory management differences, exception propagation, and the run-time dependency on the particular version of C++ libraries.
As a practical example, all libraries you use to read/write image files, XML, access USB devices, et cetera, are most likely written in C. (All the portable ones are written in C, but there are of course libraries that only work on a single hardware architecture on a single version of a specific OS.)
One of my suggestions for creating portable GUI applications is to use Python 3 and Qt for the user interface (which does not contain any features that need protecting, because any such features are trivially replicated even without the source code), and C for the underlying computation and access. This is the same model as used in e.g.
NumPy and
SciPy libraries/library collections.
In practice, the C implementations have already split the standard library, as the C compiler provides some of the functions instead of the C library. (…)
But that is not required by the language. Those are imlementation details.
That is exactly the simplistic view that kills the development of a programming language.
You see, programming languages do not evolve by the standard; the standard just codifies existing portable practices. If the standard diverges from existing practices, it becomes unreliable; if the standard ignores changes in practices, it becomes stagnant. Programmers read the standard to see what to expect from compilers, and compiler developers read the standard to understand what features the compiler should support. The features I listed above are already available in all POSIXy operating systems' standard C libraries (Linux, Mac, BSDs), and as optional libraries in Windows and historical non-POSIXy Unixes.
Even including just
getline() into the standard C library would solve an entire class of problems (line length limitations) for both new programmers and library implementors.
Currently, the best portable standard set is C99 with POSIX.1-2008. The only major OS that does not support it natively by their C library (POSIX.1 is not a separate library, but a set of additional interfaces and functions provided by the standard C libraries the OS provides), is Windows; there, you need to use shims and whatnot. It does not matter much, because only trivial code that runs on Windows runs on other OSes.
It mostly affects those learning C, because if they use Windows, they have a hard time separating what is C, and what are Microsoft extensions/weirdnesses. (For example,
fwide() does not work on Windows; you need to use a Microsoft-ism to do the same thing. Why didn't MS just include their extension weirdness inside
fwide() and make it work, is a mystery.)
So, when you train C programmers, you either use an OS other than Windows, or you spend an inordinate time explaining to them why the documentation they follow (from MS) is wrong, and why they need to go through all sorts of odd hoops to get their code working properly on Windows. Or, you let them become Microsoft C programmers, who cannot write portable code.
The whole point of C is that it is small, it is and it works.
You are conflating the C standard library (hosted environment), and the C language itself (as used in a freestanding environment).
The C language itself is small, but lacks support for important features (the status flags register in particular).
What I am suggesting, is divided into two completely separate paths. One is to include the POSIX.1 features that are already supported by all OSes in the standard C library proper, although in Windows via different interfaces. This excludes things like signals, but includes things like
getline(). Exactly what things to include should obviously be discussed; but since C99, has not at all. The other is to add features to the language itself. Unlike changes to the C library, changing the language syntax itself creates a new language. So, adding things like unordered loops or variable attributes, creates a new programming language, a C derivative.
These two paths are not mutually exclusive. Updating the C standard library would not affect existing C code, but would allow future C code to be both portable, and effective without additional dependencies. (Existing de-facto standards like opendir()/readdir()/closedir() have fatal flaws; in particular, its depth is limited by the number of
DIR* handles a process can have open at any moment, and it is very difficult to make it behave correctly when changes to the directory contents occur at the same time as the directory is scanned. Having the C library implement
glob() and
nftw() allows OS-specific tricks to avoid both of these issues. Instead of nftw(), one could also consider fts_open()/fts_read()/fts_children()/fts_set()/fts_close() from BSDs.)
Adding features to the C standard library does not affect C freestanding environments at all (say, writing a kernel, or code for a microcontroller). Because these features already exist in standard libraries (albeit with different function names and calling conventions in Windows), they would not "bloat" the standard C library either: this stuff already exists in them, I'd just want to standardize their interfaces, so that C code would be truly portable, and not need a mess of preprocessor directives to cater for the oddities in one.
Adding features to the C language itself is a much longer-term proposition; we'd be talking about one or two decades instead of years for its adoption, due to the sheer amount of existing C code. For me, it is more like an interesting research topic: what kind of language would match our uses of the existing hardware even better than C, while being easier to optimize, and not require any kind of runtime?