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