[phobos] Usage of asserts/contracts and memory safety
Jonathan M Davis
jmdavisProg at gmx.com
Wed Aug 24 20:49:09 PDT 2011
On Thursday, August 25, 2011 06:30:56 Vladimir Panteleev wrote:
> Hi,
>
> I noticed that Phobos's makefile specifies -release, however there are
> places in Phobos which use asserts and contracts. I recall there being a
> discussion regarding verification of parameters in Phobos, but I do not
> know the current consensus. DMD has -defaultlib and -debuglib switches,
> which could justify usage of asserts/contracts, but they are not used in
> the default configuration.
>
> I'm currently working on making std.socket.SocketSet memory-safe (adding
> sockets past the fd_set capacity is not currently checked), and I'd like
> to know if these checks should be done with "enforce" in the function
> body, or "assert" in "in" contracts etc.?
If it's a checking for a bug in Phobos, use assert. If it's something that
depends on the program's state rather than whether the code is correct (e.g.
failed connection), use enforce. Other than that, it gets debatable.
Certainly, do _not_ use enforce simply because asserts aren't compiled into
the binary of Phobos which is released. If someone really wants assertions in
Phobos, they can compile it in non-release mode.
Personally, I'm generally against using assert for testing arguments, since
they often depend on program state, in which case enforce is really what you
want. However, there _are_ cases where it's definitely a bug if an invalid
argument is passed to a function. The problem with in contracts is that
they're actually testing client code, not the function that they're in, so it
really should be up to the caller to determine whether an assertion or
exception should be used, but the language isn't set up to do that. There's
certainly an argument for using assertions and letting client code choose to
use enforce on its own if they want that behavior, but again, it's up for
debate.
If anything, I'd say that it's a case-by-case thing at this point. Does it
make the most sense for a particular function to assert on its arguments, in
which case the tests may never happen (e.g. if the code is compiled with -
release), or does it make the most sense to throw an failure? It's very
context-dependent.
std.datetime uses exceptions for bad arguments, whereas std.algorithm uses
assert. But if a function in std.algorithm is given a bad argument, it's
almost certainly a bug in the client code, whereas std.datetime's functions
could easily be operating on values given from I/O.
So, I'd say that you should pick whether to use assert or enforce on function
arguments based on how bad it is if the test is skipped (as happens with
assertions and -release), how performant the code must be (truly performance-
critical code may not be able to afford the cost of testing in -release mode as
would happen with enforce), and how likely it is that bad arguments are a
result of a bug in the program rather than the state of a particular run of
the program.
- Jonathan M Davis
More information about the phobos
mailing list