On Wednesday, 30 July 2014 at 22:58:01 UTC, Andrei Alexandrescu
wrote:
On 7/30/14, 3:39 PM, Joseph Rushton Wakeling via Digitalmars-d
wrote:
On 31/07/14 00:01, Walter Bright via Digitalmars-d wrote:
7. using enforce() to check for program bugs is utterly wrong.
enforce() is a
library creation, the core language does not recognize it.
A question on that.
There are various places in Phobos where enforce() statements
are used
to validate function input or class constructor parameters.
Yah, Phobos is a bit inconsistent about that. TDPL discusses
the matter: if a library is deployed in separation from the
program(s) it serves, it may as well handle arguments as
"input". That's what e.g. the Windows API is doing - it
consistently considers all function arguments "inputs", scrubs
them, and returns error codes for all invalid inputs it
detects. In contracts, the traditional libc/Unix interface does
little checking, even a strlen(NULL) will segfault.
Phobos is somewhere in the middle - sometimes it verifies
arguments with enforce(), some other times it just uses
assert().
Yeah, we're not entirely consistent with it. However, if it would
definitely be a program bug for an argument to not pass a
particular condition, then it should be an assertion, and if it's
definitely likely to be program input (e.g. this is frequently
the case with strings), then exceptions are the appropriate
approach. It's the cases where it's not obviously program input
that's more debatable. Forcing checks and throwing exceptions
incurs overhead, but it can significantly reduce programming
bugs, because it doesn't put the onus on the programmer to verify
the arguments. Using assertions is more performant but can
significantly increase the risk of bugs - particularly when the
assertions will all be compiled out when Phobos is compiled into
a library unless the function is templated.
I know that Walter favors using assertions everywhere and then
providing functions which do the checks so that the programmer
can check and then throw if appropriate, but the check isn't
forced. Personally, I much prefer being defensive and to default
to checking the input and throwing on bad input but to provide a
way to avoid the check if you've already validated the input and
don't want the cost of the check. For instance, many of the
functions in std.datetime throw (particularly constructors),
because it's being defensive, but it's on my todo list to add
functions to bypass some of the checks (e.g. a function which
constructs the type without doing any checks in addition to
having the normal constructors). Regardless, I think that using
assertions as the go-to solution for validating function
arguments is generally going to result in a lot more programming
bugs. I'd much prefer to default to being safe but provide
backdoors for speed when you need it (which is generally how D
does things).
But regardless of which approach you prefer, there are some cases
where it's pretty clear whether an assertion or exception should
be used, and there are other cases where it's highly debatable -
primarily depending on whether you want to treat a function's
arguments as user input or rely on the programmer to do all of
the necessary validations first.
- Jonathan M Davis
- assume, assert, enforce, @safe Walter Bright via Digitalmars-d
- Re: assume, assert, enforce... Andrei Alexandrescu via Digitalmars-d
- Re: assume, assert, enforce... Joseph Rushton Wakeling via Digitalmars-d
- Re: assume, assert, enforce... Andrei Alexandrescu via Digitalmars-d
- Re: assume, assert, enf... Jonathan M Davis via Digitalmars-d
- Re: assume, assert, enforce... Ary Borenszweig via Digitalmars-d
-