Still, for the average programmar 'top-C++' makes a miserable language. Want to write a simple class? You have to make a separate header file and decide what methods to inline/make virtual, etc. Want (binary) compatibility? You'll have to worry about things such as PIMPL and d-pointers.
It's a low-level language, and low-level issues will always leak into higher-level subsets. And why should one go through the effort? The old mantra "write in a higher language, rewrite what is too slow in C/C++" works fine.
This doesn't mean that you must use C or C++, but assuming that you can always rewrite the slow parts in C or C++ is inviting disaster.
I don't know what the first non-C practical OS will look like, but I hope I live to see it. I can't believe in 2011 my OS is still getting buffer overflows and memory mismanagement and all of the foibles that despite everyone loudly declaring is all the programmer's fault and not the langoage's fault, still seems to follow the language around like dog poo stuck on its shoe.
Even more so, the PyQt application had a NumPy backend and again, it performed flawlessly. The Qt application had a C++ backend that did similar computations as the Numpy backend, but with a much more painful programming process.
So in that line of thinking, I am a big proponent of having a dynamic language as frontend for low level libraries. Both Qt and the Numpy core are plenty fast for what they need to do and having a dynamic language like Python as a frontend makes programming very convenient. The best of both worlds, really.
I have never experienced Python being the bottleneck of my algorithms using these libraries.
C++ is, for many people, a Turing Tarpit: Ask yourself why you wouldn't write something in assembly, and that's why they wouldn't write it in C++.
In specific, C++ doesn't have built-in support for real garbage collection. This means a lot of the idioms I take for granted in languages like Common Lisp and Haskell, to pick two very different languages that have true gc in common, are effectively impossible in C++.
For example, I can't reliably pass complex data structures around using function composition (think f(g(h(x)))) because I can't rely on them existing from one function call to the next; an allocation may have failed somewhere up the line and now what? Adding in all the code needed to handle that isn't just a pain, it obscures the algorithm to the point I'm not programming the same way anymore. I'm not even thinking the same way anymore.
Now for a purely personal anecdote: I quite like C. I can do certain things in C about as fast as I can think of them (mostly, things involving the POSIX API and no really complex data structures). I occasionally get the notion to add some C++ to my bag of tricks; not C-With-Classes, but C++ with Boost and the STL and whatever else g++ can handle these days. I might as well learn to swim by jumping in 500 feet upstream of Niagara Falls; there's "hitting the ground running", there's "hitting the ground doing back-flips and double-somersaults", and then there's "hitting the ground juggling sharpened sabres and gently convincing hungry wolves to not eviscerate you." Honestly, it wasn't this hard to learn how to write macros in Common Lisp. I don't know if the problem is just me or if it really is that bizarre in C++-land.
C# is nice, but I wouldn't want to write a kernel in it.
Why not? :)
http://singularity.codeplex.com/
When C# is combined with Code Contracts / static verification, you get fairly clean/performant code and strong safety guarantees. I think that'd be quite nice for kernel programming.
C# takes things several steps further down the road.