[bind10-dev] whether/when to use exceptions
JINMEI Tatuya / 神明達哉
jinmei at isc.org
Fri Oct 9 03:52:39 UTC 2009
At Thu, 8 Oct 2009 20:45:42 -0400,
christos at zoulas.com (Christos Zoulas) wrote:
> | Resource leaks are certainly a common compliant against (C++)
> | exceptions, and I guess "without smart pointers" is a key here. Maybe
> | I'm naive, but in my understanding many of resource leak problems with
> | exceptions can be smartly avoided using RAII techniques (including the
> | use of smart pointers). If we decide to rely on exceptions relatively
> | heavily, I guess we should equally heavily use RAII.
>
> And then performance suffers [extra code for constructors and destructors
> and then the try / catch]. And all of that complexity for what?
To me, for improving code readability/comprehensibility by separating
exceptional cases and corresponding cleanups from the normal code
logic.
In BIND9 we often end up having code like this:
============ from here ============
do_something() {
allocate some resources;
if ((result = do_something_further()) != ISC_R_SUCCESS)
goto cleanup;
normal path follows, and return ISC_R_SUCCESS;
cleanup:
free the allocated temporary resource;
return (result);
}
do_something_further() {
allocate some resources;
if ((result = do_something_even_further()) != ISC_R_SUCCESS)
goto cleanup;
normal path follows, and return ISC_R_SUCCESS;
cleanup:
free the allocated temporary resource;
return (result);
}
do_something_even_further() {
allocate some resources;
if ((p = get_memory()) == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
normal path follows, and return ISC_R_SUCCESS;
cleanup:
free the allocated temporary resource;
return (result);
}
============ to here ============
In some extreme cases the cleanup part of the code could consume a
half of the function, which also decreases readability. Also, we've
sometimes introduced bugs of missing cleanup or cleaning up something
that's not actually allocated.
It'll make me happy if I can write the whole logic as follows:
============ from here ============
do_something() {
allocate some resources in an RAII manner
try {
do_something_further();
normal path follows, and return;
} catch (...) {
this is a rare failure case. just give up and handle next request.
}
}
do_something_further() {
allocate some resources in an RAII manner;
do_something_even_further();
normal path follows, and return;
}
do_something_even_further() {
allocate some resources;
classX* p = new classX; // this may also be in an RAII style using a smart ptr
normal path follows, and return;
}
============ to here ============
I guess Michael's motivation he explained in an earlier message is
basically the same.
Whether or not we use our own exceptions heavily, we should also note
that it's (very) difficult to make the code completely exception-free,
especially if we want to use STL (and I think we do) because we should
also expect a std::bad_alloc exception. So, I suspect we'll need to
have some try-catch anyway.
---
JINMEI, Tatuya
More information about the bind10-dev
mailing list