Re: Matching throw to catch at compile time?
Patrik Kahari wrote:
"Also, the implementation must provide some method of querying the
exception object as to its actual type (this leads directly to some
form of runtime type identification (RTTI))."
"The type descriptor is necessary because the actual exception is
handled at runtime when the object itself otherwise has no type
information associated with it. RTTI is a necessary side effect of
support for EH."
The way I imagined it; the throw statements could be seen similarly to
a function call, with the exception object as a parameter. The catch
clause could then be seen as the function itself. The rules for
function overload resolution could then be used to find the correct
catch clause from a number of overloaded catch clauses in the same
scope, at compile time. (The rules for name hiding, could similarly be
used if the there where many catch clauses with the same function
signature in the enclosing scopes.) These catch functions would be
different from regular functions in that they would have to be local
so that they could use the local variables of the enclosing function.
The catch functions would also be different in that their calls would
work the other way, up the stack instead of down. (The other parts of
exception handling would not have to be affected by this compile time
matching of throws to catches)
What's wrong with this picture?
First of all, you cannot know at compile time which caller called a
function, and thus which out of several possible catches matches a
specific throw. In some simple cases the compiler might be able to
derive this knowledge, but typically there is more than one potential
caller for a function.
The second problem is that you can also throw polymorphic classes, that
is, classes whose type cannot be derived at compile time and whose
static type is different from their dynamic type. If such a class is
thrown, the program control should go to the catch that matches the
*dynamic* type of the exception, and not the static type. Consider:
class A {...};
class B : public A { .. };
void foo()
{
B *b = new B;
try {
bar(b);
} catch(B *ex1) {
... <--- code must go here
} catch(A *ex2) {
...
}
}
void bar(A *a)
{
throw a; // static type is A*, dynamic type is *B
}
So long,
Thomas
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]