www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Casting

reply Trevor Parscal <trevorparscal hotmail.com> writes:
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
Jun 21 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
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?

Jun 21 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
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
Jun 21 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
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
Jun 21 2005
prev sibling parent reply Trevor Parscal <trevorparscal hotmail.com> writes:
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
Jun 22 2005
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
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!

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?)
Jun 22 2005
next sibling parent Trevor Parscal <trevorparscal hotmail.com> writes:
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
Jun 22 2005
prev sibling parent xs0 <xs0 xs0.com> writes:
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!

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
Jun 23 2005