Sujet : Re: We have a new standard!
De : sam (at) *nospam* email-scan.com (Sam)
Groupes : comp.lang.c++Date : 03. Jan 2025, 16:50:51
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <cone.1735919451.379621.297354.1000@ripper.email-scan.com>
References : 1 2 3 4 5 6
User-Agent : https://www.courier-mta.org/cone/
Paavo Helde writes:
>
It might be obvious to you, but not for everybody. What exact problem can be solved by validating thrown exception classes at compile time?
Ummm… Making it logically impossible to throw an uncaught exception? The code will refuse to compile because it will be ill-formed. Getting rid of std::uncaught_exception(), completely?
And how would a developer of a base class know which exceptions I might want to throw from an overridden virtual function in a derived class, which might be developed and compiled fully separately from the base class?
The developer doesn't need to figure it out, the compiler will tell him.
half-assed solution is to have all exception classes derived from a
superclass, i.e. std::exception, and then play musical chairs to catch
exceptions.
>
My Java is rusty, but isn't it in Java that all exception classes must be derived from a single superclass (Throwable)?
Not all exception classes, but all classes. But this has absolutely nothing to do, whatsoever, with validating that all exceptions will be caught by well-formed code.
Here's a free clue. Define "function X throws exception Y" if it throws that exception (and it doesn't catch it itself), or if it calls function Z that's declared (in Z's throw specifier) as throwing that exception. The compiler has all the information needed to know which exception can be thrown out of that function.
This is not C. This is C++. The compiler has the signature of every function called by code.
Then:
void throwing_function() throw(ExceptionClass)
{
}
… this function is allowed to throw ExceptionClass or any derived class. If it throws something else, it is ill-formed, and will refuse to compile.
void catching_function() // TBD
{
throwing_function();
}
One of the following must be true for the catching_function(). Either:
1) The call to throwing function must be inside a try/catch that catches either ExceptionClass or any of its superclasses, which means that this exception gets caught and does not get propagated, and catching_function() can be declared noexcept. Or throw() for all that matters. Or, at some point in the bright future all functions without a throw specification will be treated as noexcept. Until then, something else will need to be done, but that's a separate discussion.
Or:
2) The catching function must be declared as throw(ExceptionClass), or as throwing any of its superclasses, thus propagating the exception, passing the hot potato to its callers.
With this, your suffering C++ compiler can now tell you that your C0D3Z are ill-formed, unless your code is logically guaranteed to catch every thrown exception. std::uncaught_exception() is deprecated.
The issue of overriding throwing_function() or catching_function() in a subclass is orthogonal, and can be resolved consistently with the same way analogous signature differences are resolved by C++'s current rules.
This is how exceptions are handled in Java, more or less, and /that's/ how throw specifications should've been handled in C++ from the begining, instead of that mess.
I'll go even as far as stating, that either:
A) I'm missing something obvious, something fundamental to C++ that would've prevented this implementation.
B) The original implementation of throw specifiers in C++ was written by (fill in your favorite perjorative here, mine is "morons").