DIP33: A standard exception hierarchy

Jonathan M Davis jmdavisProg at gmx.com
Wed Apr 3 11:36:55 PDT 2013


On Wednesday, April 03, 2013 10:33:00 Steven Schveighoffer wrote:
> On Wed, 03 Apr 2013 01:59:32 -0400, Lars T. Kyllingstad
> 
> <public at kyllingen.net> wrote:
> > On Wednesday, 3 April 2013 at 05:42:13 UTC, Lars T. Kyllingstad wrote:
> >> The problem with assert is that it gets disabled in release mode.
> >> 
> >> I think it is a bad idea to have this be the "standard" behaviour of
> >> 
> >> parameter validation.
> > 
> > Allow me to clarify my position on assert() a bit. As a general rule, I
> > think assert() should be used to verify internal program flow and
> > program invariants, and nothing more. Specifically, public APIs should
> > *not* change depending on whether asserts are compiled in or not.
> > 
> > Say I am writing a function that you are using. I don't trust you to
> > always give me correct parameters, so I check them. (Maybe my function
> > could even do something dangerous if I didn't.)
> > 
> > public void myFunction(someArgs)
> > {
> > 
> > if (someArgs are invalid)
> > 
> > throw new InvalidArgumentError;
> > 
> > ...
> > 
> > }
> 
> I disagree here. There are two "users" involved, one is the actual user,
> typing a command on the command line, and then the developer who uses the
> function. The developer should be checked with assert, the user should be
> checked with code like you wrote.
> 
> The problem becomes apparent when developers don't check user input before
> passing to your functions. That is on them, not you. The library should
> be able to have all the safety checks removed to improve performance.

I completely agree with this. There _are_ Errors which should definitely stay 
in in release, but in general, anything relating to DbC should be removed in 
release. It's then up to the caller to decide what testing they do or don't 
want in release.

> I wish there was a way to say "this data is unchecked" or "this data is
> checked and certified to be correct" when you call a function. That way
> you could run the in contracts on user-specified data, even with asserts
> turned off, and avoid the checks in release code when the data has already
> proven valid.

That would definitely be cool, though I have no idea how we could ever 
implement that beyond creating wrapper types which indicated whether the data 
was checked or not, which would introduce extra overhead - though if you're 
willing to overload all of your functions, you could do something like

Verify!T verifyFoo(T param)
{
 //do checks...
 return Verify!T(param);
}

void foo(T param)
{
 foo(verifyFoo(param));
}

void foo(Verified!T param)
{
 ...

}

That would be rather intrusive, but you _could_ do it if you wanted to.

However, the way that contracts really _should_ work is that whether they're 
enabled or not is completely dependent on how the caller is compiler rather 
than the callee, whereas right now, other than templated code, it's based 
entirely on how the callee is compiled. That way, it's completely up to the 
caller whether the checks happen or not. But unfortunately, I don't think that 
it would ever work very well from an implementation standpoint for it to work 
that way - not as long as we're using the C linker - since you'd need a way to 
associate the contracts with the functions in a way that it was up to the 
caller to run them or not, and I don't think that that's really possible with 
how C linking works.

- Jonathan M Davis


More information about the Digitalmars-d mailing list