View mode: basic / threaded / horizontal-split · Log in · Help
June 22, 2005
Casting
OK, I have this problem...

--------------------------
class FOO
{
public:
	FOO[] Foos;
	void Add(inout FOO _newfoo)
	{
		this.Foos ~= _newfoo;
	};
}
class BAR : FOO
{
public:
	int Value;
}

FOO foo = new FOO();
BAR bar = new BAR();

foo.Add(bar);
--------------------------

I get errors saying that "foo.Add(bar);" is passing the wrong type. Now, 
it shows the type being automatically cast, but with it's still giving 
an error.

I try this...

--------------------------
class FOO
{
public:
	FOO[] Foos;
	void Add(inout FOO* _newfoo)
	{
		this.Foos ~= *_newfoo;
	};
}
class BAR : FOO
{
public:
	int Value;
}

FOO foo = new FOO();
BAR bar = new BAR();

foo.Add(cast(FOO*)&bar);
--------------------------

and it works... Why is this? How can I avoid this?

-- 
Thanks,
Trevor Parscal
www.trevorparscal.com
trevorparscal@hotmail.com
June 22, 2005
Re: Casting
Does adding "cast(FOO)" to the first example also work?

On Tue, 21 Jun 2005 21:03:27 -0700, Trevor Parscal  
<trevorparscal@hotmail.com> wrote:
> OK, I have this problem...
>
> --------------------------
> class FOO
> {
> public:
> 	FOO[] Foos;
> 	void Add(inout FOO _newfoo)
> 	{
> 		this.Foos ~= _newfoo;
> 	};
> }
> class BAR : FOO
> {
> public:
> 	int Value;
> }
>
> FOO foo = new FOO();
> BAR bar = new BAR();
>
> foo.Add(bar);
> --------------------------
>
> I get errors saying that "foo.Add(bar);" is passing the wrong type. Now,  
> it shows the type being automatically cast, but with it's still giving  
> an error.
>
> I try this...
>
> --------------------------
> class FOO
> {
> public:
> 	FOO[] Foos;
> 	void Add(inout FOO* _newfoo)
> 	{
> 		this.Foos ~= *_newfoo;
> 	};
> }
> class BAR : FOO
> {
> public:
> 	int Value;
> }
>
> FOO foo = new FOO();
> BAR bar = new BAR();
>
> foo.Add(cast(FOO*)&bar);
> --------------------------
>
> and it works... Why is this? How can I avoid this?
>
June 22, 2005
Re: Casting
On Tue, 21 Jun 2005 21:03:27 -0700, Trevor Parscal wrote:

> OK, I have this problem...
> 
> --------------------------
> class FOO
> {
> public:
> 	FOO[] Foos;
> 	void Add(inout FOO _newfoo)
> 	{
> 		this.Foos ~= _newfoo;
> 	};
> }
> class BAR : FOO
> {
> public:
> 	int Value;
> }
> 
> FOO foo = new FOO();
> BAR bar = new BAR();
> 
> foo.Add(bar);
> --------------------------
> 
> I get errors saying that "foo.Add(bar);" is passing the wrong type. Now, 
> it shows the type being automatically cast, but with it's still giving 
> an error.
> 
> I try this...
> 
> --------------------------
> class FOO
> {
> public:
> 	FOO[] Foos;
> 	void Add(inout FOO* _newfoo)
> 	{
> 		this.Foos ~= *_newfoo;
> 	};
> }
> class BAR : FOO
> {
> public:
> 	int Value;
> }
> 
> FOO foo = new FOO();
> BAR bar = new BAR();
> 
> foo.Add(cast(FOO*)&bar);
> --------------------------
> 
> and it works... Why is this? How can I avoid this?

The message I get is "cast(FOO )(bar) is not an lvalue". This happens
because when you declare a parameter as an 'inout' it means that the called
function must be passed the address of some RAM which is known to the
calling routine, but because D is doing a cast (BAR --> FOO) it thinks (I
guess) that some RAM reallocation is going on. Thus if allowed, it would
pass the address of some temporary RAM area used by the compiler to hold
the casted 'bar' and that address is not recorded anywhere for the calling
routine. To get around this, the following code works ...

   FOO foo = new FOO();
   BAR bar = new BAR();
   FOO* x;
   x = cast(FOO*)&bar;
   foo.Add(*x);

This works because I explicitly take *and* record the address of 'bar' and
pass that to the member function. 

On the other hand, why are you using 'inout'? Wouldn't a simple 'in' work?
-- 
Derek
Melbourne, Australia
22/06/2005 2:13:34 PM
June 22, 2005
Re: Casting
On Wed, 22 Jun 2005 14:21:40 +1000, Derek Parnell wrote:

Here is a reworking of your code using just 'in' ...

<code>
/* basic template file for D */
import std.stdio;

class FOO
{
public:
   static int next_id = 0;
   int id;

   FOO[] Foos;
   void Add(in FOO _newfoo)
   {
       this.Foos ~= _newfoo;
   };

   void me(){ writefln("I am #%d", id); }
   this() { id = ++next_id; }
}
class BAR : FOO
{
public:
   int Value;
}
void main()
{
   FOO foo = new FOO();
   BAR bar = new BAR();
   BAR bar2 = new BAR();
   foo.Add(bar);
   foo.Add(bar2);
   foo.me();
   foo.Foos[0].me();
   foo.Foos[1].me();
}

</code>

-- 
Derek
Melbourne, Australia
22/06/2005 2:35:48 PM
June 22, 2005
Re: Casting
Derek Parnell wrote:
> On the other hand, why are you using 'inout'? Wouldn't a simple 'in' work?

Yes, in worked fine... dumb mistake.. Thanks!

-- 
Thanks,
Trevor Parscal
www.trevorparscal.com
trevorparscal@hotmail.com
June 22, 2005
Re: Casting
Trevor Parscal wrote:
> Derek Parnell wrote:
>> On the other hand, why are you using 'inout'? Wouldn't a simple 'in' 
>> work?
> 
> Yes, in worked fine... dumb mistake.. Thanks!
> 
It was a mistake *this* time.  But it *SHOULD* work with inout. 
To me this sounds like something that should be submitted to 
d.D.bugs. (Which version of D are you using?)

(OTOH, I'm no expert.  Perhaps someone who is would care to comment?)
June 23, 2005
Re: Casting
Charles Hixson wrote:

> It was a mistake *this* time.  But it *SHOULD* work with inout. To me 
> this sounds like something that should be submitted to d.D.bugs. (Which 
> version of D are you using?)

Latest.. 0.127

-- 
Thanks,
Trevor Parscal
www.trevorparscal.com
trevorparscal@hotmail.com
June 23, 2005
Re: Casting
Charles Hixson wrote:
> Trevor Parscal wrote:
> 
>> Derek Parnell wrote:
>>
>>> On the other hand, why are you using 'inout'? Wouldn't a simple 'in' 
>>> work?
>>
>>
>> Yes, in worked fine... dumb mistake.. Thanks!
>>
> It was a mistake *this* time.  But it *SHOULD* work with inout. To me 
> this sounds like something that should be submitted to d.D.bugs. (Which 
> version of D are you using?)
> 
> (OTOH, I'm no expert.  Perhaps someone who is would care to comment?)

It shouldn't work:

class A {}
class B:A {}

void init(inout A a)
{
    a=new A;
}

void main()
{
    B b;
    init(b);
    // oops, b is not a B
}


xs0
Top | Discussion index | About this forum | D home