I disagree with both points, in fact with every statement you made. Correctness can be achieved without use of exceptions (whether this is easier or harder to do is up for debate). Next, in some cases correctness may be sacrificed for performance reasons (e.g. solving a traveling salesman problem). I find it easier to properly handle unexpected error codes than unexpected exceptions. C++ has other strong sides beside performance. Java/C# often throw exceptions in very non-exceptional cases (e.g. .Net's File.Delete method).
Nope, there's no practical way to cover all possible cases. There is always a possibility of a totally exceptional situation arising (we're only human). And then your beautiful ole error-cods returnin' function either takes down your whole application (which might result in someone dying while on life support in a hospital) or plods on with a successfull error code (leaving your program in an incorrect state). All because you didn't have a catch-all-exceptions clause.
This is why I find C++'s "nothrow" a joke, by the way. It's not within human power to guarantee that any piece of code never throws exceptions. A gamma ray might flip a bit. You never know. The only practical way to reliability is the Erlang way: be prepared for errors arising anywhere anytime, not rely on fallible notions of what can and cannot cause errors.
There is a difference between preventing a program crash and handling errors. Please don't use catch-all-exceptions clause for either, especially not in hospital machines.
The difference between writing if (status != SUCCESS) and catch (Exception) is that the former will allow the program to actually crash when it should (see panic in Rust). You should not be able to recover from OutOfMemory or GammaRayFlippedABit errors (use ECC memory to prevent that). You should restart the process (or the entire machine) because you can't hope the developer was wise enough to destroy and recreate appropriate amount of state.
The additional problem with exceptions in Java and C# is that many times you don't care about failure of some operations, but the language practically forces you to write catch-all statement to prevent a program crash, so you end up accidentally catching unrecoverable errors.
> there's no practical way to cover all possible cases
This is something that can be enforced by the language, it's just that C doesn't do so. The Zig language does, though. The result is somewhat similar to conventional exceptions. [0]
It would be possible to do the same in C if a convention were used that could be verified by static analysis. I don't know if this has ever been implemented, though.
> And then your beautiful ole error-cods returnin' function either takes down your whole application (which might result in someone dying while on life support in a hospital) or plods on with a successfull error code (leaving your program in an incorrect state).
That's not an accurate account of how critical systems are written.
Plenty are written in C, which has no support for exceptions. Some are written in the SPARK language, a subset of Ada, which essentially forbids the use of exceptions. [1]
> This is why I find C++'s "nothrow" a joke, by the way. It's not within human power to guarantee that any piece of code never throws exceptions.
That's not right. Code written in C is guaranteed never to throw an exception, as the language doesn't support them. Error codes have to be used. Code can still go wrong, and can even produce undefined behaviour, but exceptions are never raised.
I'm not very knowledgeable on the particulars of nothrow and noexcept in C++ though, I have to admit. From a quick glance, it seems that it does provide a hard assurance that a noexcept function can never throw. If a noexcept function tries to throw, the effect is to call std::terminate. [2]
> A gamma ray might flip a bit.
That won't throw an exception, it will just flip a bit. Radiation-hardening is handled by hardware, and perhaps by replication, but not by software. [3]
> The only practical way to reliability is the Erlang way: be prepared for errors arising anywhere anytime, not rely on fallible notions of what can and cannot cause errors.
Again, that certainly isn't the only way. C and SPARK are both used for life-or-death code. No-one will ever write avionics software in Erlang.