View mode: basic / threaded / horizontal-split · Log in · Help
May 05, 2007
no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
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
Re: no property 'opCall' for type ... what am I doing wrong?
"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
Top | Discussion index | About this forum | D home