Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print more when assertion fails?

Tags:

d

Real opIndex(size_t row, size_t col = 0) const pure nothrow {
  assert(col + row * Col < Row * Col, "index out of bounds.");
  return _data[col + row * Col];
}

Today this assertion failed, and I wanted to see the actual values of row and col. Unfortunetly, assert isn't like writeln or writefln, so I can't do something like:

assert(col + row * Col < Row * Col, "index out of bounds. row: %d  col: %d", row, col);

I even tried this:

assert(col + row * Col < Row * Col, "index out of bounds" ~ to!string(row)~ " " ~ to!string(col));

But I can't call to because opIndex is pure. I could temporarily remove pure from opIndex, but that triggers a long chain of undos because other pure methods are calling opIndex. Not being able to call to also eliminates the possibility of creating my own function to pass to assert.

So, What else is there to try? I just want to print such values when assertion fails.

like image 218
Arlen Avatar asked Feb 27 '12 03:02

Arlen


1 Answers

For the moment, if you want to convert to or from strings in a pure function, you're going to have to write the conversion functions yourself. Some work has gone into making functions like std.conv.to pure, but we haven't yet reached the point where they are. Too many lower level constructs still aren't pure, even if they theoretically could be. A lot of work is being put into making stuff const-correct for the next release of dmd (2.059), and some work on pure goes hand-in-hand with that, since certain functions in Object are going to have to be pure, const, @safe, and nothrow. So, there's a good chance that std.conv.to will be able to be pure for converting to and from strings with the next release. And even if it doesn't happen with the next release, it's going to happen soon, since it does need to happen (as your predicament illustrates). But until then, you're on your own.

Assuming that all of that was sorted out, then the best way to create a string for your assertion would be

assert(col + row * col < row * col,
       format("index out of bounds. row: %d  col: %d", row, col));

which will work in a impure function, but until format can be pure, it won't work in a pure one.

Now, you can put impure stuff in a debug block. So, if you wanted to, you could do

debug
{
    assert(col + row * col < row * col,
           format("index out of bounds. row: %d  col: %d", row, col));
}

but then you'd have to compile with -debug or your assertion wouldn't be run. But regardless, debug will allow you to put impure code in your your pure function for debugging purposes and will be compiled in as long as the -debug flag is used, so it can serve as a temporary workaround for the current deficiencies of format and to.

like image 88
Jonathan M Davis Avatar answered Nov 09 '22 03:11

Jonathan M Davis