These languages also had OS fully implemented on them, just with tiny bits of Assembly to do the very low level stuff, similar to what C would require anyway.
The only advantage of C is that its runtime is so small, that in practice the OS is the C's runtime.
The point you mention is only valid when using entirely static memory, which is a very rare case in real C code (only really used in a few small embedded codebases).
Exactly, and you can also do that in Go to avoid the GC.
Thanks for pointing this out.
This is often a misunderstanding from manual memory management fans. In many cases malloc()/free() also behave non-deterministic.
This is the main reason why for special types of applications, you need to have malloc()/free() implementations specially targeted to the use case at hand.
This is no different from the GC runtimes, which are coded specifically for real time applications, like avionics, for example.
Default platform malloc(3) and free(3) can be a crap indeed, but they are drop-in replaceable with the above at any time, unlike Go GC - if practical testing suggests such replacement is necessary (e.g. Firefox, Facebook servers)
The correct answer would be: depends on the concrete implementation. There are implementations with real-time guarantees.
However, assuming standard desktop OS malloc()/free() the answer is: No. These functions can execute very quickly.. or very slowly, depending on their current internal state. But you can control when they get called, which can be an important difference.
>The point you mention is only valid when using entirely static memory, which is a very rare case in real C code (only really used in a few small embedded codebases).
Depends on what you mean by "entirely static memory". No malloc() calls at all? Yes, that is rare and pretty much limited to the embedded realm I think. Memory pools however are very common in performance critical code.
Anyway, take a look at the OCaml GC. It's simple (probably simpler than glibc's malloc) and very performant particularly if you understand how it works and use it intelligently in your app.
Yes, but only because no major OS manufacturer picked them up as the main system language.
The only way a system language can become mainstream is if it is picked up by an OS vendor that makes it the default system language on their OS.
As for the bare level stuff you describe, real systems like Native Oberon proved this is possible. At ETHZ Native Oberon was used for almost everything an OS is used for.
Sadly no major vendor has got interested on the system, even after some industry attempts tried out by ETHZ.
Not really true, you have direct control over the memory layout of your data structures, and if you want to do really tricky stuff there is also the unsafe package.