digitalmars.D.learn - no property 'opCall' for type ... what am I doing wrong?
- Chad J (23/23) May 04 2007 main.d:
- Myron Alexander (11/40) May 04 2007 Chad,
- Chad J (3/51) May 04 2007 Ah, makes sense. I figured out what I was doing wrong in the original
- Daniel Keep (21/73) May 04 2007 This works:
- Chad J (8/82) May 04 2007 Yeah I like that trick. I didn't know about the copying function
- Frits van Bommel (3/6) May 05 2007 I'm surprised by this statement, and can't find a mention of it in the s...
- Daniel Keep (18/26) May 05 2007 I don't know if it's in the spec (I can't remember ever running across
- Frits van Bommel (19/37) May 05 2007 DMD automatically copies a register-argument to a local variable on the
- Daniel Keep (15/59) May 05 2007 Weird; you're right. It does work. I *swear* it didn't used to, tho.
- Jarrett Billingsley (3/7) May 05 2007 Sure you weren't trying to return the address of a parameter at the time...
- Daniel Keep (15/24) May 05 2007 I was trying to do one of two things: I was either trying to cast an
main.d: import std.stdio; struct A { int member1; } struct B { int member2; } void main() { A a; writefln( (cast(B)a).member2 ); } That code results in the following compiletime errors: main.d(16): Error: no property 'opCall' for type 'B' main.d(16): Error: function expected before (), not 1 of type int main.d(16): Error: no property 'member2' for type 'int' I am using DMD 1.014 on Windows. This seemed to work at some point in history, but not anymore. What am I doing wrong? Thanks
May 04 2007
Chad J wrote:main.d: import std.stdio; struct A { int member1; } struct B { int member2; } void main() { A a; writefln( (cast(B)a).member2 ); } That code results in the following compiletime errors: main.d(16): Error: no property 'opCall' for type 'B' main.d(16): Error: function expected before (), not 1 of type int main.d(16): Error: no property 'member2' for type 'int' I am using DMD 1.014 on Windows. This seemed to work at some point in history, but not anymore. What am I doing wrong? ThanksChad, What you are doing there is illegal code. The structs A and B are distinct types and cannot be cast to each other. If it worked in the past, then it was probably a compiler bug. Since structs do not allow for inheritance (they are value types), then the only way would be to use classes and inheritance or templates. What are you trying to achieve? Perhaps I can try to suggest a different method. Regards, Myron.
May 04 2007
Myron Alexander wrote:Chad J wrote:Ah, makes sense. I figured out what I was doing wrong in the original code. Thanks.main.d: import std.stdio; struct A { int member1; } struct B { int member2; } void main() { A a; writefln( (cast(B)a).member2 ); } That code results in the following compiletime errors: main.d(16): Error: no property 'opCall' for type 'B' main.d(16): Error: function expected before (), not 1 of type int main.d(16): Error: no property 'member2' for type 'int' I am using DMD 1.014 on Windows. This seemed to work at some point in history, but not anymore. What am I doing wrong? ThanksChad, What you are doing there is illegal code. The structs A and B are distinct types and cannot be cast to each other. If it worked in the past, then it was probably a compiler bug. Since structs do not allow for inheritance (they are value types), then the only way would be to use classes and inheritance or templates. What are you trying to achieve? Perhaps I can try to suggest a different method. Regards, Myron.
May 04 2007
Chad J wrote:Myron Alexander wrote:This works: void main() { A a; writefln( (cast(B*)&a).member2 ); } Just keep in mind that you can't take the address of a function argument, so if you do this inside a function, you have to make a copy first. I've used this trick to do all sorts of evil things like turn a structure into a ubyte[] :P -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Chad J wrote:Ah, makes sense. I figured out what I was doing wrong in the original code. Thanks.main.d: import std.stdio; struct A { int member1; } struct B { int member2; } void main() { A a; writefln( (cast(B)a).member2 ); } That code results in the following compiletime errors: main.d(16): Error: no property 'opCall' for type 'B' main.d(16): Error: function expected before (), not 1 of type int main.d(16): Error: no property 'member2' for type 'int' I am using DMD 1.014 on Windows. This seemed to work at some point in history, but not anymore. What am I doing wrong? ThanksChad, What you are doing there is illegal code. The structs A and B are distinct types and cannot be cast to each other. If it worked in the past, then it was probably a compiler bug. Since structs do not allow for inheritance (they are value types), then the only way would be to use classes and inheritance or templates. What are you trying to achieve? Perhaps I can try to suggest a different method. Regards, Myron.
May 04 2007
Daniel Keep wrote:Chad J wrote:Yeah I like that trick. I didn't know about the copying function arguments catch though, good to know. I suppose I was also used to being able to cast structs into other structs, sort of like how you can cast numeric types into other numeric types, and generalizing it to being able to cast any value type into another value type. Guess it doesn't hold though. I can always use this dereference-address trick to get around it.Myron Alexander wrote:This works: void main() { A a; writefln( (cast(B*)&a).member2 ); } Just keep in mind that you can't take the address of a function argument, so if you do this inside a function, you have to make a copy first. I've used this trick to do all sorts of evil things like turn a structure into a ubyte[] :P -- DanielChad J wrote:Ah, makes sense. I figured out what I was doing wrong in the original code. Thanks.main.d: import std.stdio; struct A { int member1; } struct B { int member2; } void main() { A a; writefln( (cast(B)a).member2 ); } That code results in the following compiletime errors: main.d(16): Error: no property 'opCall' for type 'B' main.d(16): Error: function expected before (), not 1 of type int main.d(16): Error: no property 'member2' for type 'int' I am using DMD 1.014 on Windows. This seemed to work at some point in history, but not anymore. What am I doing wrong? ThanksChad, What you are doing there is illegal code. The structs A and B are distinct types and cannot be cast to each other. If it worked in the past, then it was probably a compiler bug. Since structs do not allow for inheritance (they are value types), then the only way would be to use classes and inheritance or templates. What are you trying to achieve? Perhaps I can try to suggest a different method. Regards, Myron.
May 04 2007
Daniel Keep wrote:Just keep in mind that you can't take the address of a function argument, so if you do this inside a function, you have to make a copy first.I'm surprised by this statement, and can't find a mention of it in the spec. Do you have a reference for it?
May 05 2007
Frits van Bommel wrote:Daniel Keep wrote:I don't know if it's in the spec (I can't remember ever running across it), but I know it doesn't work. The problem is that the D calling convention allows for up to one argument to be passed using registers, which don't *have* an address, so taking the address of them doesn't always make sense. In any case, I know the compiler has barfed every time I've tried to do it... -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Just keep in mind that you can't take the address of a function argument, so if you do this inside a function, you have to make a copy first.I'm surprised by this statement, and can't find a mention of it in the spec. Do you have a reference for it?
May 05 2007
Daniel Keep wrote:Frits van Bommel wrote:DMD automatically copies a register-argument to a local variable on the stack if the address is required. As does my GDC, it seems...Daniel Keep wrote:I don't know if it's in the spec (I can't remember ever running across it), but I know it doesn't work. The problem is that the D calling convention allows for up to one argument to be passed using registers, which don't *have* an address, so taking the address of them doesn't always make sense.Just keep in mind that you can't take the address of a function argument, so if you do this inside a function, you have to make a copy first.I'm surprised by this statement, and can't find a mention of it in the spec. Do you have a reference for it?In any case, I know the compiler has barfed every time I've tried to do it...It's always worked fine for me. For instance, the following works, whether I'm using DMD or GDC: --- import std.stdio; void bar(int* x) { assert(*x == 42); writefln("*%s = %s", x, *x); } void foo(int x) { bar(&x); } void main() { foo(42); } --- (DMD 1.014, GDC 0.23/amd64)
May 05 2007
Frits van Bommel wrote:Daniel Keep wrote:Weird; you're right. It does work. I *swear* it didn't used to, tho. I remember having to work around the problem for a library I was writing and being a bit annoyed at the time... Oh well. -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Frits van Bommel wrote:DMD automatically copies a register-argument to a local variable on the stack if the address is required. As does my GDC, it seems...Daniel Keep wrote:I don't know if it's in the spec (I can't remember ever running across it), but I know it doesn't work. The problem is that the D calling convention allows for up to one argument to be passed using registers, which don't *have* an address, so taking the address of them doesn't always make sense.Just keep in mind that you can't take the address of a function argument, so if you do this inside a function, you have to make a copy first.I'm surprised by this statement, and can't find a mention of it in the spec. Do you have a reference for it?In any case, I know the compiler has barfed every time I've tried to do it...It's always worked fine for me. For instance, the following works, whether I'm using DMD or GDC: --- import std.stdio; void bar(int* x) { assert(*x == 42); writefln("*%s = %s", x, *x); } void foo(int x) { bar(&x); } void main() { foo(42); } --- (DMD 1.014, GDC 0.23/amd64)
May 05 2007
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:f1hkrr$o19$1 digitalmars.com...Weird; you're right. It does work. I *swear* it didn't used to, tho. I remember having to work around the problem for a library I was writing and being a bit annoyed at the time... Oh well.Sure you weren't trying to return the address of a parameter at the time?
May 05 2007
Jarrett Billingsley wrote:"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:f1hkrr$o19$1 digitalmars.com...I was trying to do one of two things: I was either trying to cast an inout argument into a ubyte[] or back, or trying to take the address of an argument, convert it to a ubyte[], then return a .dup of it. Basically, I was trying to do blind byte copies. -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Weird; you're right. It does work. I *swear* it didn't used to, tho. I remember having to work around the problem for a library I was writing and being a bit annoyed at the time... Oh well.Sure you weren't trying to return the address of a parameter at the time?
May 05 2007