After this project, I'd like to play with a simple OS not written in C/C++.
I mean, I like to compile (modify?) some good piece of code, upload something on a board (68k? modern STM32?), and play with it.
Ada? Pascal? Modula2? Oberon? Assembly? All welcome
Other than assembly language, those are all isomorphic to C/C++, certainly the GNU version if not the standard (e.g. with nested functions possible). They differ only in surface syntax, the standard library, and things such as how visibility of names is controlled. Generate code is identical. The same goes for Lisp.
Really? You can get buffer overflow in Ada using the normal cliche programming style? Or access/mutate aCamel as if it was aHorse?
You don't get buffer overflows in properly-written C (or especially C++) code.
I wondered how long it would be until the There's No True Scotsman fallacy would rear its head! https://en.m.wikipedia.org/wiki/No_true_Scotsman
That is an unfair statement.
Unlike C++, C has two different "modes": hosted environment and freestanding environment. The former includes the standard C library – including functions like fgets(), strcpy(), and so on –; whereas the latter is used when programming kernels and microcontrollers, often with a replacement set of functions (see Linux kernel C functions, or the Arduino environment, for examples).
Buffer overflows are intrinsic part of the C standard library, but not the C freestanding environment. It is quite possible to replace the standard C library with a completely different API, including arrays with explicit bounds and garbage collection, but keep the C compiler and syntax.
Therefore, this is not a No True Scotsman argument, because it identifies the problematic but optional half of C. I know this, because I myself am working on a "better" substitute (for my own needs and uses).
So you think it is an acceptable argument to exclude "half" of C uses and concentrate on the less inconvenient other half?
No, I think it is an error to consider hosted C environment the only valid C, and call relying on freestanding C 'excluding "half" of C', when the main problems are all in the hosted C environment only.
The above linked argument is not a case of No True Scotsman, exactly because of the dual nature of the C standard, and the problems being avoidable by using freestanding C. It is a valid argument, because many C developers are not aware of the differences between the hosted environment and the freestanding environment, and conflate the two.
(Technically, one does not even need to write freestanding C, just avoid using most of the standard C library API; and use other APIs, like say Boehm GC for memory allocation, and mutable data buffers with explicit bounds instead of standard C strings, to basically completely avoid both buffer overruns and dynamic memory management problems.)
I fully agree that the C standard committee has dropped the ball over two decades ago, mainly due to increased vendor pressure and complete rejection of the POSIX standard, and instead veering into C++ and vendor-specific optional interfaces (like the so-called "safe I/O functions", which are nothing of the sort).
Put another way, buffer overruns and dynamic memory management issues are not an inherent part of C; only an inherent part of the library that forms the core of the hosted C environment: the standard C library. It is quite possible, and indeed very feasible, to either replace, or just augment the standard C library with something completely different that 1) does not suffer from buffer overruns because array boundaries are part of the data structures used by the replacement library interfaces, and 2) has an efficient automatic garbage collection; and the code will still be C that a typical C developer will be able to read and maintain. To develop such code, a typical C developer will have to learn those new interfaces, but that's it.
Having experimented and delved into this, it amazes me that no real work has been published on this front, because I'm basically drowning in possibilities and having to write a lot of test code just to see which options
I prefer right now, for code running under the Linux kernel on typical ARM and Intel hardware.
To me, it feels like computer scientists are arguing amongst themselves how many sides should a polygonal wheel have, completely ignoring round, circular wheels... We really have not made much real progress in software engineering (and I'm suspecting in computer science too) in the last two or three decades. Small optimizations only.
Things like the Arduino library (which replaces the standard C library for Arduino development; and although the code is compiled using a C++ compiler, it relies on the GNU C++ compiler providing a freestanding C++ environment based on the C freestanding environment) are honestly quite horrible, possibly even worse than the standard C library. I shan't talk much about the various vendor-provided Hardware Abstraction Libraries, just that every single one I've seen has been a disappointment (in the software engineering sense – compare to a contractor seeing a house built with timber but using twine instead of nails or screws (or even pegs) to hold things together).
The dual nature is important to realize, because the non-library part of C is so simple yet powerful. It could be much better (code-level concurrency, barriers, memory semantics/coherency etc.), but that sort of stuff is better explored with other languages. However, the C library part, which is not a compulsory/required part of C, only an optional part, is the biggest problem with C, and is easily replaced with something else. (That is, all C compilers I have used, provide compile time flags and options that allow trivially replacing/omitting the standard C library with something else.)