Re: Automatic conversion from error codes to exception handling?
andhow wrote:
The problem seems difficult for the general case, but I find that
carefully written C system code tends to follow one of only a few
templates to implement the transactional acquisition of resources.
Surprisingly, I find the cleanest solution to be the one that uses
goto's instead of if/elses:
result = Acquire1(&res1)
if (failed(result))
goto Cleanup1;
result = Acquire2(&res2)
if (failed(result))
goto Cleanup2;
... acquire 3, 4, 5
... finish transaction
return success;
... release 5, 4, 3
Release2(res2)
Cleanup2:
Release1(res1)
Cleanup1:
return result;
Yes, this is a rather clean and systematic approach, even though it uses
goto. It is heavily used in e.g. Linux. Sometimes it can be simplified by
checking whether a resource was acquired, e.g.
res x = NULL;
...
failed:
if(x)
release(x);
This is equivalent to the following, where Resource1/2 are classes
that follow the RAII idiom:
Resource1 r1(...);
Resource2 r2(...);
... Resource{3,4,5}
... finish transaction (release resources from r1/r2 sentries)
From the code I've seen, now from several different sources, such a
transformation (manually or automatically) would represent a radical
reduction in code.
Not only that, but also it makes it easier getting code correct,
particularly in the presence of exceptions. If I have to work with legacy
APIs, I often wrap them and replace error-codes with exceptions at the
lowest possible level. The higher-level code then looks like the C code
would look if you removed all error handling.
Without knowing too much about the problem, there seem to be a lot of
practical hairy issues like how you tell the tool what types are error
codes, what success/failure is, what resources are, where are the
entry points where exceptions need to be caught and converted to error
codes, etc, but at the heart of the matter, there seems to be a fairly
regular pattern to match and substitute.
I recently posted a helper-class to the Boost mailinglist[1] which is aimed
at managing such resources. There was no feedback there, hopefully because
they are busy fixing the last few bugs in 1.34.0 and releasing 1.34.1. This
wrapper around filedescriptors, sockets or FILE*s has ownership movement
semantics like std::auto_ptr and can be configured via traits. A more
elaborate description is in the mentioned posting.
And yes, I'd really like some feedback on this!
Uli
[1] http://lists.boost.org/Archives/boost/2007/05/122359.php
--
Sator Laser GmbH
Gesch??ftsf??hrer: Ronald Boers, Amtsgericht Hamburg HR B62 932
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]