Contracts or Exceptions?

Ali Çehreli acehreli at yahoo.com
Wed Mar 30 11:01:01 PDT 2011


On 03/30/2011 08:42 AM, Kai Meyer wrote:

 > we were talking about what sort of things you can do to
 > increase performance

Sorry to change the topic. :) I am fortunate that what I currently work 
on does not require more than being careful about not using the wrong 
algorithms and data structures.

 > if (good data)
 > do work
 > else
 > report "can't do work"

That is helpful as long as the data can be checked up front, but we 
can't always be sure:

if (file_exists()) {
     use_file();   // <-- the file may not exist

or

if (server_is_up()) {
     talk_to_server();  // <-- the server may not be up

 > Would be faster than:
 >
 > try
 > do work
 > catch
 > report "can't do work"

Apparently that's what Denis' (spir) measurements show as well and 
that's very unfortunate. I would like to put that slowness under the 
"quality of implementation" category. Although, it's well known that 
exception handling has been slow (e.g. in C++) in general too.

(Note: I heard that scope(failure) is lowered to a try-catch block by 
the compiler; so it should be slow too.)

If exceptions are inherently slow, that must be because they provide 
more than what we compare them against. A good example is comparing old 
features of C to C++. Some people claim that calling virtual functions 
is slow due to jumping off the vtbl. Correct, but let's not forget that 
achieving the same in C would be slow too.

Your examples do have such a feature difference: the code that uses the 
try-catch block will always execute the code in the catch clause. On the 
other hand, the code that checks the data before hand may not report 
"can't do work", as "do work" may get complicated in the future and may 
call a function that may throw directly or indirectly. And suddenly the 
function doesn't work anymore and the changes that we've made are 
detached from this function. Bad bug! :)

We may argue that exceptions should not exist in D (or C++) but they are 
so helpful (hey, I know we all know these :)):

- exceptions make it impossible (or very hard) to continue with bad 
program state

- they allow functions to return objects by freeing the return value 
from always being an error code (return values are preferable to side 
effects)

- they eliminate boiler plate error management lines (To complicate 
matters, when a function needs to do cleanup after an error, it may call 
other functions that may return more error codes. We must be careful not 
to change the value of the original error code variable.)

- they result in less lines of code (bugs live in lines of code :))

I would like to show two functions written in C and C++. To my 
knowledge, they are well written and don't have any resource leaks:

// a C function

int bar_C(Resource ** in_out)
{
     int err = 0;

     Resource * r0 = NULL;
     Resource * r1 = NULL;

     err = allocate_resource(&r0);
     if (err) goto finally;

     err = allocate_resource(&r1);
     if (err) goto finally;

     /* ... use r0 and r1 here ...  */

     if (err) goto finally;

     /* transfer ownership */
     *in_out = r0;
     r0 = NULL;

finally:

     deallocate_resource(&r1);
     deallocate_resource(&r0);
     return err;
}

// The equivalent C++ function

Resource bar_CPP()
{
     Resource r0(/* ... */);
     Resource r1(/* ... */);

     /* ... use r0 and r1 here ... */

     /* transfer ownership */
     return r0;
}

Of course the latter takes advantage of other features of C++, but it 
also shows that there is no explicit error management when the code 
relies on exceptions. bar_CPP() just does what it is supposed to do. 
Yes, there may be errors but bar_CPP() doesn't care. And the callers may 
or may not catch the errors, but bar_CPP() doesn't care.

 > I'm not sure D's exceptions are much different than C++'s.

Yeah, it must be the same as what Digital Mars C++ compiler uses. 
(Except, D also has the 'finally' clause.)

In summary: I hope I will never go back to pass-the-error-code style of 
coding.

Ali



More information about the Digitalmars-d-learn mailing list