Contracts or Exceptions?
Kai Meyer
kai at unixlords.com
Tue Mar 29 15:40:18 PDT 2011
On 03/29/2011 12:40 PM, Mike Linford wrote:
> Hello,
>
> So I'm writing a function for a library. It takes a struct as an
> argument. The struct's fields can't just be any old values, though. The
> function won't work if some of the fields are weird. It could return an
> erroneous value, or even crash.
>
> The thing is, though, that I can't tell whether the best approach is to
> use an in-contract or throw an exception if it doesn't pass my test. What
> would you guys recommend?
>
>
>
I was given two words of advice on exceptions:
"Use exceptions for the exceptional"
"Use exceptions only for the exceptional"
Meaning, if you expect something to fail frequently, using a try/catch
is much more expensive than an if/else. "The exceptional" is something
that should rarely ever occur, like running out of memory.
For contracts, they are usually meant as a developer tool to warn them
when that they will be in no-man's land if they attempt to proceed any
further. They are, therefore, not compiled in when you pass the D
compiler the -release flag.
I don't think that contracts and exceptions are mutually exclusive. They
provide two different safeguards. One is a tool to aid in the
development process, one is a tool to safeguard against exceptional
run-time scenarios.
However, I think if I rephrase your question a little bit, it might
provide you what I think you're after. I'm making an assumption here, so
I may be way off the mark.
"Who's responsibility is it to check whether or not the data passed into
the function is valid? Should I accept whatever the user wants to pass
in, and let them know when it's invalid, or should I trust that the user
is sending in good data?"
I think that's a choice for you to make. Contract programming is often
used to put the burden of validation on the user of the library (meaning
programmer writing software taht uses your library). Exceptions could be
used to indicate that the library writer is accepting responsibility for
validating the data before using it.
But validating data is not the only reason to use exceptions, and it's
not unusual for a library to skip all validations and force the user to
do all the checking before hand. Arrays are a good example. When not in
-release mode, array boundaries are checked upon every access to the
array, and an exception is thrown if access goes out of bounds. In
-release mode, if you go out of bounds you get a segfault. This is one
example of giving the user (programmer) of arrays the responsibility to
check boundaries so that the library can focus on being fast.
I think the choice comes down to a balance between performance,
responsibility, and maintainability. (Oh, and you'll usually get it
wrong the first time, so don't be sad.)
More information about the Digitalmars-d-learn
mailing list