Improving assert-printing in DMD
Jonathan M Davis via Digitalmars-d
digitalmars-d at puremagic.com
Tue Sep 29 19:22:58 PDT 2015
On Tuesday, 29 September 2015 at 21:02:42 UTC, Nordlöw wrote:
> As a follow-up to
>
> https://github.com/D-Programming-Language/phobos/pull/3207#issuecomment-144073495
>
> I starting digging in DMD for logic controlling behaviour of
> assert(), especially whether it's possible to add automatic
> printing of `lhs` and `rhs` upon assertion failure if
> `AssertExp` is a binary expression say `lhs == rhs`.
>
> After grepping for `AssertExp` the only possible place I could
> think of was
>
> ToElemVisitor::visit(AssertExp *ae)
>
> inside
>
> elem *toElem(Expression *e, IRState *irs)
>
> in file e2ir.c.
>
> Questions:
>
> 1. Is this the right place where this lhs-rhs-printing logic
> should be added? If so could somebody tell me how to make this
> happen?
>
> 2. Is it possible to from within DMD generate expressions that
> do
>
> `import std.stdio : write`
>
> and then calls write on the `lhs` and `rsh`...or this a
> completely wrong approach to solving this problem?
Several years ago, I proposed a really nice function called
assertPred which did all this kind of stuff for you, and it
supported a bunch of different operations - e.g.
assertPred!"=="(a, b), assertPred!"+=(a, b, result),
assertPred!"opCmp"(a, b). But it was ultimately rejected with the
decision being that we'd improve assert to do this instead (which
lost out on some of the fancier overloads of assertPred but would
be great for the common case). However, after some work was
actually done to implement that, it was finally decided that it
was too expensive to put it into assert:
https://issues.dlang.org/show_bug.cgi?id=5547
So, the proposed alternative to assertPred which got it rejected
ultimately got rejected itself.
But as great as assertPred was, it turns out that turning all of
your checks in unit tests into templated functions rather than
just using assert, results in a lot of template bloat, and unit
tests require more memory and take longer to compile. So, I've
pretty much gotten to the point where I think that it's just
simplest to use assert as-is and then go back and tweak your unit
test to print out the information you need if there's a failure.
Any information in a unit test that isn't reproducible should
already have been being printed on failure anyway (e.g. the seed
value for the random number generator), so it really shouldn't be
a big deal to tweak a test to print out what's going on. As nice
as it might be to have the assertion print out better
information, I don't think that it's worth adding a function just
for that. It's just too expensive in terms of compilation time
and memory.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list