assume, assert, enforce, @safe

Tofu Ninja via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 31 10:32:49 PDT 2014


On Thursday, 31 July 2014 at 17:10:27 UTC, H. S. Teoh via 
Digitalmars-d wrote:
> 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

With that logic(and the proposed optimizations that this whole 
thing is about), weird stuff like this happens...

void foo(int x)
{
     if(x != 0) throw ...;
     assert(x == 0);
}

The if check could be removed because assert will be assumed to 
always be true in release... so x could never not equal 0.... the 
assert just nuked my scrubbing logic...


More information about the Digitalmars-d mailing list