Thread overview
Casting
Jun 22, 2005
Trevor Parscal
Jun 22, 2005
Regan Heath
Jun 22, 2005
Derek Parnell
Jun 22, 2005
Derek Parnell
Jun 22, 2005
Trevor Parscal
Jun 22, 2005
Charles Hixson
Jun 23, 2005
Trevor Parscal
Jun 23, 2005
xs0
June 22, 2005
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
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
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
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
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
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
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
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