Bug 1424 – is ( Type Identifier == function) Problems with inout/out/ref parameters

Status
RESOLVED
Resolution
DUPLICATE
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2007-08-16T17:23:00Z
Last change time
2014-02-16T15:21:28Z
Keywords
wrong-code
Assigned to
nobody
Creator
dbiehl
Blocks
3106

Comments

Comment #0 by dbiehl — 2007-08-16T17:23:28Z
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 ***