1) you have rightly pointed out all the authors of the Linux kernel are total idiots who don't understand C.
2) It turns out writing a kernel isn't possible in pure C, and the kernel requires some carefully designed and considered methods of accessing all of raw memory, in various unusual ways.
This one is the case. Writing a kernel is not possible in pure C. I'm asking - given this, why are they trying to do that? Write the parts which aren't expressible in C using assembly, where they can get the semantics they want.
While technically this means your kernel is "gcc c" rather than "true c", this doesn't cause a practical problem. I know gcc, clang and visual studio's c++ standard libraries require a flat address space and 8 bit bytes, for example, but I've never seen anyone bothered by this.
How about this as a compromise: use GCC, with all its flags, to generate the assembly, and just use that? Skip the messy transition step.
Instead we could just mark some files as "These C files have to be run with GCC versions X to Y", problem solved. Then why not just compile everything with those versions of GCC?
Is it solved? You'd still have to check the generated assembly of the entire file after every change you make, to make sure it didn't have some knock-on effect that optimised something differently, even if you kept the version of the compiler the same.
And is GCC deterministic? I don't know - do you? Did you know it has a flag `-frandom-seed`?
[Edit: I am almost sure that the only part of Linux on i386 and amd64 that is written in assembly is the bootloader stub at the beginning of "Linux kernel image" file format. And it is somewhat funny and relevant that this part depends on abusing gas to generate 16bit code]
The "correct" way to do this is to write the bare minimum assembly needed to present this view to a programmer in C (so there's no need to worry about undefined behavior), then write standards compliant code from there. Writing all this code in C is just papering over the fact that what you're doing is architecture-specific and should be treated as such.
Obviously at the application level it's frowned upon, but in the kernel? You do what you have to with the tools you have.
Think about Java. Yea sure, keep telling us sun.misc.Unsafe isn't legit. It's going to get use until that capability exists elsewhere.
I'd rather my kernel not have a security hole in it because a compiler decided to optimize out undefined code: https://lwn.net/Articles/342330/
I appreciate using software that is actually written with security first, performance second in mind.
Today, if you were starting a kernel project from scratch, I'd think Rust would deserve a good, hard look.