Jump to page: 1 2
Thread overview
no property 'opCall' for type ... what am I doing wrong?
May 05, 2007
Chad J
May 05, 2007
Myron Alexander
May 05, 2007
Chad J
May 05, 2007
Daniel Keep
May 05, 2007
Chad J
May 05, 2007
Frits van Bommel
May 05, 2007
Daniel Keep
May 05, 2007
Frits van Bommel
May 05, 2007
Daniel Keep
May 05, 2007
Daniel Keep
May 05, 2007
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 05, 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?
> 
> Thanks

Chad,

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 05, 2007
Myron Alexander wrote:
> 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?
>>
>> Thanks
> 
> 
> Chad,
> 
> 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.

Ah, makes sense.  I figured out what I was doing wrong in the original code.  Thanks.
May 05, 2007

Chad J wrote:
> Myron Alexander wrote:
>> 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?
>>>
>>> Thanks
>>
>>
>> Chad,
>>
>> 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.
> 
> Ah, makes sense.  I figured out what I was doing wrong in the original code.  Thanks.

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/
May 05, 2007
Daniel Keep wrote:
> 
> Chad J wrote:
> 
>>Myron Alexander wrote:
>>
>>>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?
>>>>
>>>>Thanks
>>>
>>>
>>>Chad,
>>>
>>>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.
>>
>>Ah, makes sense.  I figured out what I was doing wrong in the original
>>code.  Thanks.
> 
> 
> 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
> 

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.
May 05, 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:
>> 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?

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/
May 05, 2007
Daniel Keep wrote:
> 
> Frits van Bommel wrote:
>> 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?
> 
> 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.

DMD automatically copies a register-argument to a local variable on the stack if the address is required. As does my GDC, it seems...

> 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:
>>
>> Frits van Bommel wrote:
>>> 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?
>>
>> 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.
> 
> DMD automatically copies a register-argument to a local variable on the stack if the address is required. As does my GDC, it seems...
> 
>> 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)

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/
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?


« First   ‹ Prev
1 2