Safety/purity and assert/enforce error messages
Jonathan M Davis
jmdavisProg at gmx.com
Thu Sep 12 13:28:54 PDT 2013
On Thursday, September 12, 2013 13:21:26 H. S. Teoh wrote:
> On Thu, Sep 12, 2013 at 04:07:24PM -0400, Jonathan M Davis wrote:
> > On Thursday, September 12, 2013 12:42:34 H. S. Teoh wrote:
> > > On Thu, Sep 12, 2013 at 09:12:18PM +0200, bearophile wrote:
> > > > H. S. Teoh:
> > > > >In phobos git HEAD, std.format has been made pure @safe nothrow
> > > > >(and CTFE-able), so you should be able to write your assert as:
> > > > >assert(condition, format("x = %s, blahblah", x));
> > > >
> > > > With the latest DMD from updated GIT head:
> > > >
> > > >
> > > > import std.string: format;
> > > > void main() pure nothrow {
> > > >
> > > > string x = "hello";
> > > > bool condition = true;
> > > > assert(condition, format("x = %s, blahblah", x));
> > > >
> > > > }
> > > >
> > > >
> > > > It gives:
> > > >
> > > > test.d(5): Error: 'std.string.format!(char, string).format' is not
> > > > nothrow
> > > > test.d(2): Error: function 'D main' is nothrow yet may throw
> > >
> > > [...]
> > >
> > > Oops. Apparently I wrote nothrow but forgot to test it. I did test
> > > pure and @safe, though, so at least those two should work.
> >
> > format can't be nothrow, because it throws when you screw up the
> > format specifiers. You have to wrap it in a try-catch block and
> > assert(0) in the catch block if you want to put it in a nothrow
> > function. std.datetime does this in at least a few places.
>
> [...]
>
> Right. Makes me wanna suggest adding this template to std.exception:
>
> auto assumeWontThrow(alias fun, T...)(T args) nothrow {
> try {
> return fun(args);
> } catch(Exception) {
> // You broke your promise, I die.
> assert(0);
> }
> }
>
> Then you can write things like:
>
> int mayThrow(int arg) {
> if (arg < 0) throw new Exception(...);
> return BBN(arg);
> }
>
> int iWontThrow() nothrow { // <-- N.B. this function is nothrow
> static assert(123 > 0);
> return assumeWontThrow!mayThrow(123);
> }
Sounds like a good suggestion, though an actual implementation should have an
error message in the assert(0). You could also implement it as a lazy
parameter like enforce and assertNotThrown do (which I think is more user-
friendly), but that would likely be less efficient due to how lazy doesn't get
optimized very well (or at least, it's my understanding that it doesn't).
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list