www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Class templates: bug?

reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
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.
Jul 14 2005
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
Try reversing the declaration order of func and myLilFunction.
Jul 14 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:db7fo2$15kp$1 digitaldaemon.com...
 Try reversing the declaration order of func and myLilFunction.

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?
Jul 14 2005
parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Andrew Fedoniouk wrote:
 "Walter" <newshound digitalmars.com> wrote in message 
 news:db7fo2$15kp$1 digitaldaemon.com...
 
Try reversing the declaration order of func and myLilFunction.

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) :-)
Jul 15 2005
parent reply David Medlock <noone nowhere.com> writes:
Deewiant wrote:

 Andrew Fedoniouk wrote:
 
"Walter" <newshound digitalmars.com> wrote in message 
news:db7fo2$15kp$1 digitaldaemon.com...


Try reversing the declaration order of func and myLilFunction.

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
Jul 15 2005
next sibling parent David Medlock <noone nowhere.com> writes:
David Medlock wrote:

 Deewiant wrote:
 
 Andrew Fedoniouk wrote:

 "Walter" <newshound digitalmars.com> wrote in message 
 news:db7fo2$15kp$1 digitaldaemon.com...


 Try reversing the declaration order of func and myLilFunction.

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

Oops, scratch that didn't realize you may have wanted funct vs delegate. Thats an interesting way to add some functionality to a class without building in a method. -DavidM
Jul 15 2005
prev sibling parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
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.
Jul 15 2005
parent reply David Medlock <noone nowhere.com> writes:
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
Jul 15 2005
parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
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.)
Jul 15 2005
parent reply David Medlock <noone nowhere.com> writes:
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); }
Jul 15 2005
parent Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
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 ;-)
Jul 15 2005
prev sibling parent =?ISO-8859-15?Q?Thomas_K=FChne?= <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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 -----BEGIN PGP SIGNATURE----- iD8DBQFDEYjD3w+/yD4P9tIRAo1tAJ9JNa3v+IWuqBkTpuLkQM4/xokTVQCfS26r MeTPI7wOFXcTOxb+v9Trw+4= =SLeu -----END PGP SIGNATURE-----
Aug 28 2005