assume, assert, enforce, @safe

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 31 10:08:49 PDT 2014


On Thu, Jul 31, 2014 at 02:05:29AM +0000, Tofu Ninja via Digitalmars-d wrote:
> On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:
> 
> >3. Use of assert to validate input is utterly wrong and will not be
> >supported. Use such constructs at your own risk.
> 
> When exactly is it 'ok' to use assert then?
> 
> If asserts are not allowed to be used to verify inputs.... then by
> extension, they can not be used to verify any derivative of an input.

No that doesn't make sense. The idea behind input sanitization is that
user-facing APIs receive arbitrary, unverified input from outside, and
before you use that data, you scrub it. After scrubbing it, it's
perfectly OK to use assert to verify its validity -- because if it's
still invalid, there's a bug in your scrubbing algorithm. The scrubbed
input *is* a derivative of the input, but you can't say that you can't
use assert on it!

(And if you *don't* scrub your data before using it, your design is
flawed and should be fixed.)


> So by that definition, asserts are only ok to use on any thing known
> at compile time... that makes them utterly useless....

Your definition is wrong. ;-) The idea behind asserts is that you're
verifying *program logic*, not checking arbitrary input data. If you
have an algorithm that computes a square root, for example, you'd use an
assert to verify that the square of the result equals the input --
because if not, that means something has gone wrong with your square
root algorithm. But you shouldn't use an assert to verify that the input
to the square root algorithm is a valid numerical string -- because the
user could have typed "abc" instead of a number. Rather, you should
scrub the user input and throw an exception when the input is invalid.

After scrubbing, however, it's perfectly valid to assert that the input
must be a valid number -- because if not, it means the *logic* in your
scrubbing algorithm is flawed (perhaps it missed a corner case).

It's true, however, that this simple idea is not always so simple in
practice. One has to draw a line between "user input" and "internal
state" somewhere, and it's not always obvious where that line falls. For
example, viewed as a whole, the entire software application may be
considered a system that takes input from outside, so "user input" means
things like keystrokes, mouse movements, etc.. But internally, the
system may consist of multiple components, and when data is passed
between components, should they be treated as "internal state" or "user
input"? Should library APIs treat application input as "external input"
and vet it before use, or is it OK to use assert to enforce(!) the
validity of data passed internally between the application's components?
It's not always easy to decide, and sometimes judgment calls have to be
made.


T

-- 
If creativity is stifled by rigid discipline, then it is not true creativity.


More information about the Digitalmars-d mailing list