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

Reply via email to