While there are arguments over when and how to use exceptions, I think this is the first time I've seen them positioned as a killer feature of C++.
While there are arguments over when and how to use exceptions, I think this is the first time I've seen them positioned as a killer feature of C++.
It's not a killer feature of C++, it's a requirement, without exceptions you can't have faillible ctors meaning your object lifecycle suddenly becomes a lot more complicated and full of additional traps.
I covered this option:
> your object lifecycle suddenly becomes a lot more complicated and full of additional traps.
because without ctors you don't have object invariants as you have to split instantiation and initialisation, or you have to implement bespoke and unusual strategies drawing you further and further away from anything which could be described as "standard" C++, thus making the advantages of C++ dwindle further into the distance. And all that with, as far as I know, no standard tooling to support you.
Classe invariants must be kept in each method call, not only constructors and destructors, and again they only matter in classes.
C++ is a multi-paradigm language, this is not Python Zen.
As a related but separate thought, sometimes adding invalid states to an object is useful. For example, take a look at std::thread::detach. Sometimes you see rvalue qualifiers on such methods (indicating the object has been consumed).
If you consider memory allocation to be infallible, there is a lot of stuff that can be written as pretty normal c++ without exceptions. The STL even pretty much works without throwing given this. If you consider allocation to be fallible you're going to have a bad time with "standard" c++ too.
And detaching a thread is pretty much always a bad idea.
The problem is not the ability to do it but the ability to enforce it. "Just be careful" has not worked, and will keep not working. Google's coding standard has not stopped C++ from causing them problems.
> As a related but separate thought, sometimes adding invalid states to an object is useful. For example, take a look at std::thread::detach. Sometimes you see rvalue qualifiers on such methods (indicating the object has been consumed).
You know what's actually useful and good?
For the object to actually be consumed and not be accessible at all anymore.
> If you consider memory allocation to be infallible
Which you can't in the kernel.
> If you consider allocation to be fallible you're going to have a bad time with "standard" c++ too.
Yes? That would be the point.
Disabling exceptions gives you C with classes, which is the old style.
I write ultra low-latency system-level code for HFT, and I certainly use exceptions.
Clearly, modern C++ has very little to do with exceptions, or I would have required them or found them useful at some point. I’m not saying exceptions are not useful, but their centrality to the language is empirically false given the vast number of modern C++ code bases that don’t use them and lose nothing by it.
Also when speaking about kernels, it isn't as if the other languages being discussed (including C), make use of their respective stdlib in kernel space.
If your process doesn’t survive allocation in bootstrap then it is badly misconfigured. If it survives bootstrap, then the software has been able to make hard guarantees about its resource constraints; the runtime will optimize to those constraints. Many years ago, given the designs of the time, you had to worry about blowing out the stack memory occasionally in edge cases, but even that isn’t a real problem these days due to changes in how it is done.
You would design things this way in any language. The benefit from a software design standpoint is that you can derive an enormous number of invariants from these constraints that can be used to guarantee that the core processes will never experience resource exhaustion. This eliminates a massive number of edge cases that would have to be accounted for if resource exhaustion was detected by testing limits.