L-Soft LISTSERV(R) 1.8e
View: Next message | Previous message
Next in topic | Previous in topic
Next by same author | Previous by same author
Previous page (November 2000, week 1) | Back to main DOTNET page
Join or leave DOTNET
Reply | Post a new message
Search
Options:   Chronologically | Most recent first
Proportional font | Non-proportional font

Date:         Mon, 6 Nov 2000 10:04:57 -0800
Reply-To:     dotnet discussion <DOTNET@DISCUSS.DEVELOP.COM>
Sender:       dotnet discussion <DOTNET@DISCUSS.DEVELOP.COM>
From:         Eric Gunnerson <ericgu@MICROSOFT.COM>
Subject:      C# and exception specifications

Note that this isn't a full discussion; there are several important rationale that aren't contained here. It does, however, present one rationale quite well (certainly better than I have...), and I think it's worthwhile to post it, even in an incomplete form. ------------------------------------------------------------------ Why doesn't C# require exception specifications? ------------------------------------------------------------------ Some languages allow or require member signatures to include exception specifications. E.g., in C++, a method that raises an ArgumentException can be declared with: void F(int a) throw (MyException) {...} and in Java such a method can be defined as void F(int a) throws MyException {...} C# neither requires nor allows such exception specifications. Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result -- decreased productivity and little or no increase in code quality. Requiring exception specifications would decrease developer productivity because of the sheer proliferation of exception specifications. This proliferation proceeds in two dimensions: The number of members. Modern exception handling allows a division of work between the code that raises the exception and the code that handles it. These pieces of code may be separated by intervening code. E.g., A calls B, B calls C, C calls D, and D raises an exception that is eventually handled by A. If C# required exception specifications, then each of A, B, C, and D would have to contain exception-handling related code even though only A and D do any actual work related to the exception. The number of possible exceptions. The number of exceptions is unquestionably large. E.g., any code that adds two numbers could result in an overflow exception, any code that divides two numbers could result in a divide by zero exception, and any code that instantiates an object could result in an out of memory exception. The lack of an increase in code quality is related to the response of developers to the proliferation of exception specifications. Developers who carefully examine all of the exception specification errors reported by the compiler might see an increase in code quality, but this would come at the expense of productivity. On the other hand, some developers will respond to the errors by mindlessly adding whatever exception specifications the compiler requires, and others will choose to subvert the intent of the language designers by adding a generic exception specification to every member. The former option is unlikely to increase code quality. The latter option effectively makes exception specifications optional -- every member is required to have a "throws Exception" clause but this doesn't actually communicate any information or require any thought. A better strategy is for client code -- code that is using a class library -- to include both generic exception handling and specific exception handling. Generic exception handling is performed centrally, and generically deals with all exceptions. Specific exception handling checks for a smaller number of exceptions -- the ones that the client code is specifically prepared to respond to or recover from. This split between generic and specific exception handlers is practically required since some exceptions (e.g., out of memory exceptions) can occur in many program locations but are rare in frequency. All client code needs to have some generic exception handling. It is interesting to note that neither Java nor C++ is strict about requiring exception specifications: Java provides support for both checked and unchecked exceptions, and (in a "do as I say and not as I do" wrinkle) many of the Java-defined exceptions are unchecked exceptions. A class author is supposed to judge whether the exception can occur "at many points in the program" and whether "recovery would be difficult or impossible" in order to make a decision about whether to employ a checked or unchecked exception. We think that this is an impossible decision to make since these factors are highly dependent on the code that is using the class rather than the class itself. The C++ language standard requires struct exception checking, but this standard is commonly ignored by tools, including Visual C++. Given the proliferation of exception specifications (see above) and the lack of compiler enforcement, it is hard to imagine that a complex class library could actually get the exception specifications right. If the exceptions are "just for documentation purposes" then we think they belong in the documentation rather than the code. Which leads me to the documentation question. The class library documentation is automatically generated from C#'s XML-based in-source documentation. For instance, the code below can be compiled with the /doc option to produce an accompanying XML file. Here's the code: using System; class Test { /// <summary> /// The F method does not do anything interesting. /// </summary> /// <param name="x">the value to F</param> /// <exception type="cref=ArgumentException">If the argument is negative.</exception> static void F(int x) { if (x < 0) throw new ArgumentException(); Console.WriteLine("F({0})", x); } static void Main(string[] args) { try { F(0); F(-1); } catch(ArgumentException) { Console.WriteLine("ArgumentException"); } } } Here is the accompanying XML file that is generated: <?xml version="1.0"?> <doc> <assembly> <name>scratch</name> </assembly> <members> <member name="M:Test.F(System.Int32)"> <summary> The F method does not do anything interesting. </summary> <param name="x">the value to F</param> <exception type="cref=ArgumentException">If the argument is negative.</exception> </member> </members> </doc> We then use the generated file to automatically produce documentation. You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.


Back to: Top of message | Previous page | Main DOTNET page

DISCUSS.DEVELOP.COM CataList Powered by LISTSERV(R)