July 15, 2005
David Medlock wrote:
> Deewiant wrote:
> 
>> David Medlock wrote:
>>
>>> Deewiant wrote:
>>>
>>>
>>>> David Medlock wrote:
>>>>
>>>>
>>>>> Deewiant wrote:
>>>>>
>>>>>
>>>>>
>>>>>> Andrew Fedoniouk wrote:
>>>>>>
>>>>>>
>>>>>>> class Foo(TYPE) {
>>>>>>> void func(int function(TYPE a) theParameter = myLilFunction) {}
>>>>>>> int function(TYPE a) myLilFunction;
>>>>>>> }
>>>>>>>
>>>>>>> Shouldn't it be as:
>>>>>>>
>>>>>>> static int function(TYPE a) myLilFunction;
>>>>>>>
>>>>>>> at least?
>>>>>>>
>>>>>>
>>>>>>
>>>>>> Evidently it does - if I try to call foo.func() I get "need 'this' to
>>>>>> access member myLilFunction". Making myLilFunction static solves
>>>>>> that.
>>>>>> Apparently func() is believed to be static, or what?
>>>>>>
>>>>>> Why can't I have a nonstatic function member in a class template? In this case I can fortunately live without it, but it makes life harder.
>>>>>>
>>>>>> And why do I need to reverse the declaration order - surely that, at
>>>>>> least, is a bug? It messes up my style of having private members
>>>>>> after
>>>>>> public ones (myLilFunction was private in the case I got this
>>>>>> from) :-)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Changle the two _function_ declarations to _delegate_ and it
>>>>> works.(along with reversing order)
>>>>>
>>>>> -DavidM
>>>>
>>>>
>>>>
>>>>
>>>> The code becomes:
>>>> -- 
>>>> class Foo(TYPE) {
>>>>    int delegate(TYPE a) myLilfunction;
>>>>    void func(int delegate(TYPE a) theParameter = myLilfunction) {}
>>>> }
>>>>
>>>> void main() {
>>>>    Foo!(int) foo = new Foo!(int);
>>>>    foo.func();
>>>> }
>>>> -- 
>>>> And it still gives me "need 'this' to access member myLilFunction". Doesn't work, unless I missed something.
>>>>
>>>> In my larger case, it also changes something else: I have a constructor taking a "int function(TYPE a)" which has a default argument that it assigns to myLilFunction. Changing it to a delegate also causes the error "literals cannot be class members" - which, BTW, sounds like it should also be given the error with the function type, but it isn't. And, BTW, this crashes the compiler in the same way as in my posts "Taking address of function literal crashes compiler" and "Another compiler crasher" - Windows says that "dmd.exe encountered a problem", et cetera.
>>>
>>>
>>>
>>> I would call that a bug.
>>>
>>> You can make a workaround :
>>>
>>>  void func(int delegate(TYPE a) theParameter = null)
>>>  {
>>>    if ( theParameter is null ) theParameter = myLilfunction;
>>>  }
>>>
>>> Not as elegant, but it works.
>>>
>>> -DavidM
>>
>>
>>
>> That basically works, but doesn't allow me to call the function without getting an "Error: Access Violation". Slightly more complicated code illustrating that:
>> -- 
>> class Foo(TYPE) {
>>     alias int function(TYPE a) funcT;
>>     funcT myLilfunction;
>> 
>>     this(funcT foo = function int(TYPE a) { return a + 1; }) {
>>         myLilfunction = foo;
>>     }
>>     void func(TYPE a, funcT theParameter = null) {
>>         if (theParameter is null)
>>             theParameter = myLilfunction;
>>         // oh noes!
>>         myLilfunction(a);
>>     }
>> }
>> void main() {
>>     int function(int a) woot = function int(int a) {return a + 2;};
>> 
>>     Foo!(int) foo = new Foo!(int)();
>>     // ***
>>     // Foo!(int) foo = new Foo!(int)(woot);
>> 
>>     foo.func(4);
>> }
>> -- 
>> The line under the "oh noes!" comment is what causes the Access Violation.
>>
>> Also notable is that if I use the line under the "***" comment instead of the one above it, passing the function literal to the class, I get a "Symbol Undefined" error when linking:
>>
>> Error 42: Symbol Undefined _D4asdf5Foo_i3Foo14__funcliteral3FiZi
>>
>> (The more I try and get this to work, the more convinced I get that what I'm trying to do is not even supported - hopefully not permanently and/or intentionally so.)
> 
> 
> 
> I am not sure why those things are happening, but here is a version which works:
> 
> -DavidM
> 
> --- begin code
> 
> import std.stdio;
> class Foo(TYPE) {
>     alias int function(TYPE a) funcT;
>     funcT myLilfunction;
> 
>     this(funcT foo = null) {
>       if ( foo is null ) {
>         foo = function int(TYPE a) { writefln( a + 1 ); return a+1; };
>       }
>         myLilfunction = foo;
>         assert( myLilfunction != null );
>     }
> 
>     void func(TYPE a, funcT theParameter = null) {
>         if (theParameter is null)
>             theParameter = myLilfunction;
>             assert( myLilfunction != null );
>         // oh noes!
>         myLilfunction(a);
>     }
> }
> void main() {
>     int function(int a) woot = function int(int a) {writefln(a+2);
> return a + 2;};
> 
>     Foo!(int) foo = new Foo!(int)();
>     foo.func(4);
> 
>   Foo!(int) foo2 = new Foo!(int)(woot);
>   foo2.func(20);
> 
> }

Many thanks, that works. This was my mistake really - of course I should have applied the same workaround to the constructor as well.

Still, I think this should be considered a bug. After all, if it can be made to work with these workarounds (swap declaration order, null-checks instead of normal default parameter) then either we should disallow the workarounds as well or make it work more intuitively.

Preferably the latter ;-)
August 28, 2005
Deewiant schrieb:

> DMD 0.128, Windows XP SP2.
> --
> class Foo(TYPE) {
> 	void func(int function(TYPE a) theParameter = myLilFunction) {}
> 
> 	int function(TYPE a) myLilFunction;
> }
> 
> void main() {
> 	Foo!(int) foo = new Foo!(int);
> }
> --
> DMD gives me:
> 
> asdf.d(2): cannot implicitly convert expression (myLilFunction) of type
> int(*)(TYPE a) to int(*)(int a)
> asdf.d(8): template instance asdf.Foo!(int) error instantiating
> asdf.d(8): Foo!(int) is used as a type
> asdf.d(8): new can only create structs, dynamic arrays or class objects,
> not void's
> asdf.d(8): cannot implicitly convert expression (new void*) of type
> void* to asdf.Foo!(int).Foo
> 
> IMHO the relevant error is the first one, the rest are just caused by it.
> 
> Why doesn't myLilFunction get properly instantiated? The compiler recognises that in theParameter, TYPE is int, but not that it's also int in myLilFunction?
> 
> Enlighten me if I'm doing something wrong.


Added to DStress as http://dstress.kuehne.cn/run/f/forward_reference_13_A.d http://dstress.kuehne.cn/run/f/forward_reference_13_B.d http://dstress.kuehne.cn/run/f/forward_reference_14_A.d http://dstress.kuehne.cn/run/f/forward_reference_14_A.d

Thomas

1 2
Next ›   Last »