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