We recently got hit by a bug where some method threw an exception which it was not supposed to. Since the thrown exception was not in the methods documented list of exception classes we did not have a catch for it and landed up with an unhandled exception crash. These kind of things are really bad when they originate from WinForm event handlers as there is no catch all block for every event and uncaught exceptions just terminate the form. 

My instant reaction was this wouldn't have happened if we had checked exceptions  in C#. However, there has been a lot of debate on the inclusion of checked exception (as in Java) into C#. Ander's Hejlsberg has a great rational on this topic here. I think we need a good solution with this exception business, Java's solution is not good enough and C++ throw list is simply crap.

Checked Exceptions as in Java

<All Java code in this blog was written and tested with VJ# >

Checked exceptions mean that every method is supposed to declare the various exceptions it can throw in the method's signature. The compiler then proceeds with static analysis to ensure that the method throws only those exceptions that it had declared or exceptions derived from them.

public class A extends Exception

{

}

public class B extends Exception

{

}

public class C extends B

{

}

public class Program

{

public static void func() throws B

{

throw new A(); // compilation failure

throw new B(); // OK

throw new C(); // OK as C extends B

}

}

In the Java code above the compilation fails when we try to throw A as it does not derive from B. The compiler not only verifies that the method throws only the correct exceptions it also verifies that the caller handles all those exceptions. By "handle" the caller either needs to catch these exceptions or include them in its throws list.

public class B extends Exception

{

}

public class C extends B

{

}

public static void func() throws B

{

throw new C();

}

For the above code you have two options of calling func

public static void foo()

{

try {

func();

}

catch (B b) {

// ...

}

}

or

public static void foo() throws B

{

func();

}

In a micro sample like the one above checked exceptions looks super cool. So there is no need for documentation of list of exceptions. The compiler ensures that a method does not do anything sneaky and throw an exception it was not supposed to and it also ensures that you take care of all exceptions and do not become the author of a culprit method.

However, in large real-life projects the whole idea starts breaking down. For an excellent discussion on this read Hejlsberg's comment

C++ throw list (Exception specification)

I cannot stop myself from stating that this is one of the most crappiest feature (??) in C++. First lets see how it works

int foo() throw (B)

{

throw new A();

}

int bar() throw ()

{

throw new A();

}

as in Java you can give a list of exceptions that the class can throw. If the list is empty then the method is not supposed to throw any exception. The problem is that this is totally misleading to most programmers and makes them believe that this list is enforced as in Java. The truth is that it isn't. So the above code will compile just fine. The fact that foo is throwing A when its supposed to throw B and that bar is throwing A when its not supposed to throw any, is not checked by the compiler. This is more of exception specification (read fancy compiler supported documentation).

What the compiler does is that when an exception is thrown which does not match the specification the global unexpected() handler is called at runtime. Since rarely you can do something intelligent in the global handler, you'd need to live with the terminate() call from there and watch in horror as your program dies miserably. The whole of this happens at run-time and there is no static check.

So simply put the general guidelines is almost always "do not use exception specification". Sometimes however, the empty throw() is allowed as this can help the compiler optimize generated code as it need not take care of all the stack unwinding stuff. However, if you do get an exception in code you've marked with throw(), just pray and hope that the comp just does't burn itself down....

Microsoft Visual C++ compiler does the right thing of just parsing and ignoring the throw list (exception specification). I think the time spent on implementing the C++ spec on this would've been waste of time and no-value would 've been added.

C# and Spec#

C# wisely (IMO) does not include checked exception. However, Spec# from Microsoft Research does implement this. Read about spec# implementation here. Spec# follows Java is its implementation and it used data-flow rules like the ones used in definite assignment to verify this.

Since C# picks up a lot of things from Spec# (and COmega) I expected this to move into C#. Atleast for C#3.0 the announced plans do not include checked exceptions in C#....