View mode: basic / threaded / horizontal-split · Log in · Help
March 21, 2009
Returning a struct by reference
Hi there!

I'm quite new at D and I'm still just playing with it, but there is a thing that I find currently missing. Sometimes, I'd like to be able to return a struct by reference and not by value. For example, in the following example:

struct Position {
  float x;
  float y;
}

class Object {
  private Position m_position;

  public Position position() {
     return m_position;
  }
}

I'd like to be able to write things like this: myObject.position.x = 43 to actually change the position of the object. But right now, since "position" is a struct, it is returned by value and not by reference, and then the previous instruction won't change the position of the object, but it will work on a copy of the position field.


Here is the solutions that I can see to this problem:

- Returning a pointer to the position: "public Position *position() { ... }", but I'd like to keep my code as free from pointers as possible.
- Make "Position" a class and not a struct. That could be a solution, but then, when I'll do things like "Position pos = object.position; pos.x = 43;", it will effectively change the position of the object, which I wouldn't like with this syntax.

Actually, I'd like to be able to do a thing like this:
  public ref Position position() {
     return m_position;
  }
which would be the equivalent form to passing structs by reference in a parameter.

Is there a way to do this in D?

Regards,
Simon
March 21, 2009
Re: Returning a struct by reference
Simon TRENY wrote:
> Hi there!
> 
> I'm quite new at D and I'm still just playing with it, but there is a thing that I find currently missing. Sometimes, I'd like to be able to return a struct by reference and not by value. For example, in the following example:
> 
> struct Position {
>    float x;
>    float y;
> }
> 
> class Object {
>    private Position m_position;
> 
>    public Position position() {
>       return m_position;
>    }
> }
> 
> I'd like to be able to write things like this: myObject.position.x = 43 to actually change the position of the object. But right now, since "position" is a struct, it is returned by value and not by reference, and then the previous instruction won't change the position of the object, but it will work on a copy of the position field.
> 
> 
> Here is the solutions that I can see to this problem:
> 
> - Returning a pointer to the position: "public Position *position() { ... }", but I'd like to keep my code as free from pointers as possible.
>  - Make "Position" a class and not a struct. That could be a solution, but then, when I'll do things like "Position pos = object.position; pos.x = 43;", it will effectively change the position of the object, which I wouldn't like with this syntax.
> 
> Actually, I'd like to be able to do a thing like this:
>    public ref Position position() {
>       return m_position;
>    }
> which would be the equivalent form to passing structs by reference in a parameter.
> 
> Is there a way to do this in D?

Yes. Make the variable public.

class Object {
	Position position;
}

This code is even simpler than your's above. Incredible, isn't it?

> Regards,
> Simon
>
March 21, 2009
Re: Returning a struct by reference
grauzone Wrote:

> Simon TRENY wrote:
> > Hi there!
> > 
> > I'm quite new at D and I'm still just playing with it, but there is a thing that I find currently missing. Sometimes, I'd like to be able to return a struct by reference and not by value. For example, in the following example:
> > 
> > struct Position {
> >    float x;
> >    float y;
> > }
> > 
> > class Object {
> >    private Position m_position;
> > 
> >    public Position position() {
> >       return m_position;
> >    }
> > }
> > 
> > I'd like to be able to write things like this: myObject.position.x = 43 to actually change the position of the object. But right now, since "position" is a struct, it is returned by value and not by reference, and then the previous instruction won't change the position of the object, but it will work on a copy of the position field.
> > 
> > 
> > Here is the solutions that I can see to this problem:
> > 
> > - Returning a pointer to the position: "public Position *position() { ... }", but I'd like to keep my code as free from pointers as possible.
> >  - Make "Position" a class and not a struct. That could be a solution, but then, when I'll do things like "Position pos = object.position; pos.x = 43;", it will effectively change the position of the object, which I wouldn't like with this syntax.
> > 
> > Actually, I'd like to be able to do a thing like this:
> >    public ref Position position() {
> >       return m_position;
> >    }
> > which would be the equivalent form to passing structs by reference in a parameter.
> > 
> > Is there a way to do this in D?
> 
> Yes. Make the variable public.
> 
> class Object {
> 	Position position;
> }
> 
> This code is even simpler than your's above. Incredible, isn't it?

Ok, but then, what if I'd like to make the variable "read-only"? i.e. preventing the user from writing things like this:
myObject.position = pos2;

> 
> > Regards,
> > Simon
> >
March 21, 2009
Re: Returning a struct by reference
Simon TRENY wrote:
> Ok, but then, what if I'd like to make the variable "read-only"? i.e. preventing the user from writing things like this:
> myObject.position = pos2;
> 

So... you're rejecting a solution on the basis that it prevents you from
doing the exact opposite of what you want to do?

*boggle*

 -- Daniel
March 21, 2009
Re: Returning a struct by reference
Simon TRENY wrote:
> grauzone Wrote:
> 
>> Simon TRENY wrote:
>>> Hi there!
>>>
>>> I'm quite new at D and I'm still just playing with it, but there is a thing that I find currently missing. Sometimes, I'd like to be able to return a struct by reference and not by value. For example, in the following example:
>>>
>>> struct Position {
>>>    float x;
>>>    float y;
>>> }
>>>
>>> class Object {
>>>    private Position m_position;
>>>
>>>    public Position position() {
>>>       return m_position;
>>>    }
>>> }
>>>
>>> I'd like to be able to write things like this: myObject.position.x = 43 to actually change the position of the object. But right now, since "position" is a struct, it is returned by value and not by reference, and then the previous instruction won't change the position of the object, but it will work on a copy of the position field.
>>>
>>>
>>> Here is the solutions that I can see to this problem:
>>>
>>> - Returning a pointer to the position: "public Position *position() { ... }", but I'd like to keep my code as free from pointers as possible.
>>>  - Make "Position" a class and not a struct. That could be a solution, but then, when I'll do things like "Position pos = object.position; pos.x = 43;", it will effectively change the position of the object, which I wouldn't like with this syntax.
>>>
>>> Actually, I'd like to be able to do a thing like this:
>>>    public ref Position position() {
>>>       return m_position;
>>>    }
>>> which would be the equivalent form to passing structs by reference in a parameter.
>>>
>>> Is there a way to do this in D?
>> Yes. Make the variable public.
>>
>> class Object {
>> 	Position position;
>> }
>>
>> This code is even simpler than your's above. Incredible, isn't it?
> 
> Ok, but then, what if I'd like to make the variable "read-only"? i.e. preventing the user from writing things like this:
> myObject.position = pos2;

Then you write a getter that simply returns the field by value.

The D compiler will (hopefully) inline the getter function, so there 
shouldn't be a disadvantage in performance.

Note: I think D2.0 wants to introduce ref-returns at some point in the 
future.

>>> Regards,
>>> Simon
>>>
>
March 21, 2009
Re: Returning a struct by reference
grauzone Wrote:

> Simon TRENY wrote:
> > grauzone Wrote:
> > 
> >> Simon TRENY wrote:
> >>> Hi there!
> >>>
> >>> I'm quite new at D and I'm still just playing with it, but there is a thing that I find currently missing. Sometimes, I'd like to be able to return a struct by reference and not by value. For example, in the following example:
> >>>
> >>> struct Position {
> >>>    float x;
> >>>    float y;
> >>> }
> >>>
> >>> class Object {
> >>>    private Position m_position;
> >>>
> >>>    public Position position() {
> >>>       return m_position;
> >>>    }
> >>> }
> >>>
> >>> I'd like to be able to write things like this: myObject.position.x = 43 to actually change the position of the object. But right now, since "position" is a struct, it is returned by value and not by reference, and then the previous instruction won't change the position of the object, but it will work on a copy of the position field.
> >>>
> >>>
> >>> Here is the solutions that I can see to this problem:
> >>>
> >>> - Returning a pointer to the position: "public Position *position() { ... }", but I'd like to keep my code as free from pointers as possible.
> >>>  - Make "Position" a class and not a struct. That could be a solution, but then, when I'll do things like "Position pos = object.position; pos.x = 43;", it will effectively change the position of the object, which I wouldn't like with this syntax.
> >>>
> >>> Actually, I'd like to be able to do a thing like this:
> >>>    public ref Position position() {
> >>>       return m_position;
> >>>    }
> >>> which would be the equivalent form to passing structs by reference in a parameter.
> >>>
> >>> Is there a way to do this in D?
> >> Yes. Make the variable public.
> >>
> >> class Object {
> >> 	Position position;
> >> }
> >>
> >> This code is even simpler than your's above. Incredible, isn't it?
> > 
> > Ok, but then, what if I'd like to make the variable "read-only"? i.e. preventing the user from writing things like this:
> > myObject.position = pos2;
> 
> Then you write a getter that simply returns the field by value.
> 
> The D compiler will (hopefully) inline the getter function, so there 
> shouldn't be a disadvantage in performance.

If I add a getter-property that returns the field by value, the following instruction "object.position.x = 12;" won't modify the position of the object, but will only modify the returned copy of the position, right?
That's actually why I'd like to have a getter that returns the field by reference and not by value.

> 
> Note: I think D2.0 wants to introduce ref-returns at some point in the 
> future.
> 
> >>> Regards,
> >>> Simon
> >>>
> >
March 21, 2009
Re: Returning a struct by reference
Hello Simon,

> If I add a getter-property that returns the field by value, the
> following instruction "object.position.x = 12;" won't modify the
> position of the object, but will only modify the returned copy of the
> position, right?
> 
> That's actually why I'd like to have a getter that returns the field
> by reference and not by value.
> 


That is correct. Reference returns are on the todo list. For now this Hack 
should work.


struct S { float x; float y; }


class C
{
   S s

   class C_S { void x(float v){ s.x=v; } void y(float v){ s.y=v; } }

   C_S pos() { return new C_S(); }
}
Top | Discussion index | About this forum | D home