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