From: Richard Peters (R.A.Peters_at_[hidden])
Date: 2002-08-01 04:06:11
David Brownstein wrote:
>> I was reading the following message, and it took me down a completely
>> different path... I'd like to propose a small utility class, if
>> there is interest.
>> I noticed that remove() is a function that returns void, AND throws
>> exceptions to report various error conditions. Generally this kind
>> of usage of exceptions (using exceptions as an alternative way of
>> reporting an error when a return value would suffice) really bothers
>> me, because 1) there is considerable overhead that is avoidable
>> using normal return values, and 2) if a programmer "forgets" to
>> capture/check a return value, the reported failure *might* not halt
>> program execution, but failure to use a try/catch block will!
IMHO, this is completely the wrong direction. It always bothers me if return values
are misused as error codes. When a function returns a value, it should be the result
of a calculation, that is what functions do. When a function can't fullfill its
postcondition, it has to report that as an error. If you want to return a special
errorcode, you have to widen the postcondition, which makes it harder for
programmers to use the function. This is much more readable/usable:
Postcondition: !exists( ph )
Compared to this:
Postcondition: !exists( ph ) || return_value != 0
And you aren't ready there, because you should add things like
Postcondition: !exists( ph ) || (return_value != 0 && (return_value == -1 when
file not found) && (return_value == -2 when some other error) etc.
Also, you can't use it consistently. Functions that do return values (not errors)
can't report errors this way. They'll continue to use exceptions. You then have one
set of functions where you should check the return value, and one set of functions
where you have to write a try/catch block.
Your firts argument might be true, some people do care about performance. I do not,
but maybe you can persuade the makers of seperating the functions into low/high
functions or so. You can build a safe library on top of a fast one, but not the
other way around. I dunno if that's practical though.
I don't think that your second argument holds. If a programmer forgets to check
return values, you can forget about the correctness of your program. You might end
up thrashing all data, destroy a lot of work, etc. If you forget to catch an
exception, at least you don't just destroy your data. Exception catchers somewhere
else in your code could actually save a lot of work, by last-minute recovery or
something like that.
>> Anyway, I realize that one of the reasons exceptions are used to
>> report error conditions is the ability to transmit additional
>> information about the error. The std::logic_error is a good example
>> of this- the CTOR takes a const string&, which allows the user to
>> throw an excpetion and provide a description of the error. The
>> "consumer" can use the logic_error.what() method to extract the
>> SO- wouldn't it be nice if we could have an error return that
>> supported return codes (like true|false, or -1, etc.), and also
>> allow the reporting of a human readable description (a la
>> std::logic_error)? To this end I have written a simple class, with a
>> (type templated) return value combined with a description string. It
>> is attached here, embedded in a simple test program. Let me know if
>> this is interesting...
>> David Brownstein
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk