against enforce

Steven Schveighoffer schveiguy at yahoo.com
Fri Mar 25 13:49:29 PDT 2011


On Fri, 25 Mar 2011 16:23:08 -0400, spir <denis.spir at gmail.com> wrote:

> This logic certainly looks sensible, but I cannot understand how it  
> should work in practice. Say I'm implementing a little set of operations  
> on decimals. Among those, some (division, square root...) will  
> necessarily have to check their input.

You can look at it in a simple way:  If this branch of code will always  
run the same way every time (i.e. is deterministic), then using assert is  
desired.  Why?  Because the assumption is that you test that code via unit  
tests.  Once you test it, and it works, there is no reason to test it  
again.

For example, if I do:

sqrt(1);

There is never ever a need to test this in production code.  sqrt(1) is  
always 1, and will always work.

If I do:

sqrt(-1);

There is never ever a need to test this in production code.  sqrt(-1) is  
always a failure, and will always fail.  Unit tests should catch this code  
before it is released.

But if I do something like:

auto file = File.open("/tmp/xyz.txt"); // did not look up usage for File,  
may be wrong

Then I always want this to be tested, even in release mode, because there  
are environments beyond the program's control that will cause an error.   
Similar to this, user input needs to be validated even in production code.

So if you had:

int main(string[] args)
{
sqrt(to!int(args[0]));
}

this means args[0] should be checked that it is a valid positive integer.

The problem with this whole utopian idea is, the code that is responsible  
for knowing how to check its input is the function.  The code that knows  
whether the input needs to be checked during release is the caller.  So  
there is no way to convey to sqrt "hey, this input I'm sending in is  
externally-generated, check it during production too, ok?".  If we had  
options for that, the API quickly becomes unwieldly.

Of course, knowing that sqrt takes only positive numbers, we could do this  
check outside the sqrt function, but far more complex functions may not be  
so easy to validate input for.  And why should the caller be responsible  
for validating the input?

What I feel like we need is a compiler feature like:

validate(sqrt(to!int(args[0]));

which essentially calls sqrt with asserts and contracts *enabled*, even at  
production time.  This way you could choose while writing code how  
essential a particular call is to check the input, but re-use the  
already-in-place contracts for that function.

This might be a feature that's totally not worth the effort.  But I can't  
see a good way to solve this without having some sort of mechanism.  It  
also shouldn't throw an AssertError, since that would kill the program  
instantly.

-Steve


More information about the Digitalmars-d mailing list