On 2018-07-31 09:17, Shachar Shemesh wrote:
I'm trying to figure out what's the signature of the built-in assert. It
does not seem that I can define a similar function myself.
First attempt:
void myAssert(bool cond, string msg) @nogc nothrow;
No, because msg gets evaluated unconditionally.
void myAssert(bool cond, lazy string msg) @nogc nothrow;
test.d(8): Error: @nogc function test.myAssert cannot call non-@nogc
delegate msg
void myAssert(bool cond, lazy string msg @nogc nothrow ) @nogc nothrow;
test.d(4): Error: found @ when expecting )
test.d(4): Error: semicolon expected following function declaration
test.d(4): Error: no identifier for declarator nogc
test.d(4): Error: declaration expected, not )
test.d(9): Error: unrecognized declaration
Templates to the rescue!!!
void myAssert(STR)(bool cond, lazy STR msg );
test.d(14): Error: @nogc function D main cannot call non-@nogc function
test.myAssert!string.myAssert
Based on what Steven said and what I found in the spec, this seems to
work with the current language [1]:
extern (C) int printf(in char*, ...) @nogc nothrow;
void myAssert(bool cond, string delegate() @nogc nothrow[1] msg ...)
@nogc nothrow
{
msg[0]();
}
string param() @nogc nothrow
{
printf("bar\n");
return "foo";
}
void main() @nogc nothrow
{
myAssert(false, param());
}
This prints "bar". But if the delegate is not called, then nothing is
printed.
The signature of "myAssert" is bit ugly and not straightforward to
understand, but it works. I think it should be possible to specify
attributes for lazy parameters or they should be automatically inferred.
Is there an issue for this reported?
[1] https://run.dlang.io/is/g4Rm1w
--
/Jacob Carlborg