Assert and the optional Message

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Mar 10 09:04:42 PST 2012


On Sat, Mar 10, 2012 at 08:48:32AM -0800, Jonathan M Davis wrote:
> On Saturday, March 10, 2012 16:53:42 Jacob Carlborg wrote:
> > On 2012-03-09 18:59, H. S. Teoh wrote:
[.[..]
> > > I agree, though, that catching Errors outside of unittests is a
> > > very, very bad idea in general.
> > 
> > I don't see what's so bad in making AssertError an exception instead of
> > an error.
> 
> Then
> 
> catch(Excetion e) {}
> 
> would catch it. This would be a huge problem in normal code.
> Assertions are supposed to kill the program. This is specifically
> mentioned in TDPL.
[...]

It seems that what we need is for assert errors called from within a
unittest to throw Exceptions, whereas assert errors not called from a
unittest should throw Errors. Something like:

	auto func(T args...)
	in {
		if (args.are_bad()) {
			static if (__called_from_unittest__)
				throw new AssertException(...);
			else
				throw new AssertError(...);
		}
	} body { ... }

However. The unittest is usually testing for a *specific* assert, so
turning *all* asserts into an exception is very bad. For example, if the
unittest is checking for assert errors caused by bad arguments, but
while running the code it throws an assert error caused by memory
corruption. It would be *very* bad for the unittest to catch this error
and then continue running, because now the program is in a bad state.

Hmm. The more I think about it, the more I'm leaning towards simplifying
contracts so that most, if not all, of any complicated checks happen in
an external function (i.e. outside the contract), which can be
unittested separately. Unittesting things that throw assertion errors is
just a minefield rife with potentially very nasty problems.


T

-- 
2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.


More information about the Digitalmars-d-learn mailing list