Hi,
I have some strange problems with IsExpression and inout/out/ref parameters,
first some code:
-------------- SNIP ---------------
//version = WithBar;
//version = BarWithParameterTypeTuple;
//version = DgWithParameterTypeTuple;
//version = WithAlsoFooParams;
import std.traits;
import std.stdio;
void foo(ref int i) {
}
static if (is(typeof(foo) P == function))
alias P FooParams;
else
static assert(0);
version(WithAlsoFooParams) {
static if (is(typeof(foo) P == function))
alias P AlsoFooParams;
else
static assert(0);
}
version(DgWithParameterTypeTuple) {
void function(ParameterTypeTuple!(foo)) dg;
} else {
void function(FooParams) dg;
}
version(WithBar) {
version(BarWithParameterTypeTuple) {
void bar(ParameterTypeTuple!(foo)) {
}
} else {
void bar(FooParams) {
}
}
}
int main(string[] args)
{
int i = 0;
writefln(typeof(&foo).stringof);
writefln(typeof(dg).stringof);
version(WithBar)
writefln(typeof(&bar).stringof);
return 0;
}
-------------- SNIP ---------------
I first define a function "foo", now I want to define a delegate "dg" with the same parameters as foo. I get the parmeter tuple of foo with the isExpression. The output of the code is:
void(*)((ref int))
void(*)((ref int))
how it should be. Now want to define a second function "bar" with the same parameters as foo (Simple uncomment the first line "version = WithBar;"), I thought the output is something like this, with a ref-Parameter:
void(*)((ref int))
void(*)((ref int))
void(*)((ref int))
but the output is:
void(*)((int _param_0))
void(*)((int _param_0))
void(*)((int _param_0))
where is the ref parameter in all lines?
Now get the parameter tuple of foo for function bar with the std.traits.ParameterTypeTuple template. (uncomment the second line "version = BarWithParameterTypeTuple;") The output is:
void(*)((ref int))
void(*)((ref int))
void(*)((int _param_0))
where is the ref in the last line?
until here everything compiles fine, but now I define a second alias of the parameter tuples of foo (uncomment the 4. line "version = WithAlsoFooParams" the and I get "Stack Overflow" from the DMD compiler and GDC hangs.
I try it with DMD versions 1.020, 2.003 and a SVN Trunk Version (Rev 139) of GDC .
Greets Daniel
Comment #1 by htvennik — 2010-04-26T06:44:29Z
I think the point is that 'ref' is a storage class, not part of the parameter's type. Therefore it isn't preserved in TypeTuples theoretically. In practice the 'ref' is preserved in the result of ParameterTypeTuple!(), but using that in a template to define the parameters of a templated function, will only take the types, not the 'ref'.
It's not always practical like this, and it makes me write a lot of work-arounds, but solving this issue in D is problematic. It either requires one of:
- make type tuples preserve storage class (and how to get rid of it then, if you don't want it to be preserved?)
- make 'ref' and 'out' part of the type (and what about 'lazy' then? make it unfold to a delegate type?)
I don't really feel for either one...
Comment #2 by yebblies — 2011-06-10T10:47:20Z
Marking as a duplicate as the report seems to expect this behaviour.
*** This issue has been marked as a duplicate of issue 1818 ***