Reading TDPL about function and delegate literals (5.6.1)
auto f = (int i) {};
assert(is(f == function));
I've got an assertion failure. Is this assertion correct?
I tried the following:
int z = 5;
auto f = (int i) { return i < 5; };
auto d = (int i) { return i < z; };
assert(is(typeof(f) == typeof(d)));
Assertion is valid there. Actually f is a delegate, not a function even if it doesn't need a frame pointer to access local variables. Is this a bug?
Also, I do not understand how assert(is(f == function));
should work.
I tried assert(is(f == delegate));
but it was failed also. What's wrong?
I use DMD32 D Compiler v2.053
UPDATE
auto f = (int i) {};
assert(is(typeof(f) == delegate))
Works correct, although there is no reason to be a delegate
But
auto f = function (int i) {};
assert(is(typeof(f) == void function(int))); // correct
assert(is(typeof(f) == function)); // failed!!!!!
Miracle. It seems D2 is not ready for production use yet.
"f" is a variable. The is expression compares types. This should work:
assert(is(typeof(f) == delegate));
If you want to create a function instead of a delegate, you can use the function literal syntax:
auto f = function (int i) { ... };
assert(is(typeof(f) == function)); // should be true
If the function literal syntax is not used, the literal is assumed to be delegate (Expressions, look under "Function Literals". This makes sense because D should not change the type based on the whether the body of the literal needs the stack frame (this would be super screwy). EDIT: TDPL does actually specify that the compiler will infer a function instead of a delegate if it can, regardless of the "function" keyword. This seems like a poor idea to me, so this might be something that has been dropped.
As to why the is(f == function) doesn't work, this looks like a regression.
You might find isFunctionPointer and isDelegate helpful.
See this, taken from traits.d
:
template isSomeFunction(/+@@@BUG4217@@@+/T...)
if (/+@@@BUG4333@@@+/staticLength!(T) == 1)
{
enum bool isSomeFunction = isSomeFunction_bug4333!(T).isSomeFunction;
}
private template isSomeFunction_bug4333(T...)
{
/+@@@BUG4333@@@+/enum dummy__ = T.length;
static if (is(typeof(& T[0]) U : U*) && is(U == function))
// T is a function symbol.
enum bool isSomeFunction = true;
else static if (is(T[0] W) || is(typeof(T[0]) W))
// T is an expression or a type. Take the type of it and examine.
static if (is(W F : F*) && is(F == function))
enum bool isSomeFunction = true; // function pointer
else enum bool isSomeFunction = is(W == function) || is(W == delegate);
else enum bool isSomeFunction = false;
}
I think it might explain some things.
In other words:
void main()
{
static if (is(typeof(&main) T : T*)) static assert( is(T == function));
static if (is(typeof(&main) U)) static assert(!is(U == function));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With