Thread overview
Returning a struct by reference
Mar 21, 2009
Simon TRENY
Mar 21, 2009
grauzone
Mar 21, 2009
Simon TRENY
Mar 21, 2009
Daniel Keep
Mar 21, 2009
grauzone
Mar 21, 2009
Simon TRENY
Mar 21, 2009
BCS
March 21, 2009
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
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
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

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
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
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
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(); }
}