digitalmars.D.bugs - Class templates: bug?
- Deewiant <deewiant.doesnotlike.spam gmail.com> Jul 14 2005
- "Walter" <newshound digitalmars.com> Jul 14 2005
- "Andrew Fedoniouk" <news terrainformatica.com> Jul 14 2005
- Deewiant <deewiant.doesnotlike.spam gmail.com> Jul 15 2005
- David Medlock <noone nowhere.com> Jul 15 2005
- David Medlock <noone nowhere.com> Jul 15 2005
- Deewiant <deewiant.doesnotlike.spam gmail.com> Jul 15 2005
- David Medlock <noone nowhere.com> Jul 15 2005
- Deewiant <deewiant.doesnotlike.spam gmail.com> Jul 15 2005
- David Medlock <noone nowhere.com> Jul 15 2005
- Deewiant <deewiant.doesnotlike.spam gmail.com> Jul 15 2005
- =?ISO-8859-15?Q?Thomas_K=FChne?= <thomas-dloop kuehne.cn> Aug 28 2005
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
Try reversing the declaration order of func and myLilFunction.
Jul 14 2005
"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
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
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
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
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
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
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
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
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
-----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









David Medlock <noone nowhere.com> 