www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Passing structs by reference

reply imr1984 <imr1984_member pathlink.com> writes:
Ok im sorry to bring this up again, but Im still very peaved by this. At the
moment here are the ways to pass large structs for example by reference in D:

-use a pointer (*) 
-use inout
-use out 

None of these are acceptable for passing references that are for reading only.
The in keyword should be changed so that it passes by reference.

Why hasnt this problem been fixed?
May 25 2005
next sibling parent reply Vathix <vathix dprogramming.com> writes:
On Wed, 25 May 2005 11:56:12 -0400, imr1984 <imr1984_member pathlink.com>  
wrote:

 Ok im sorry to bring this up again, but Im still very peaved by this. At  
 the
 moment here are the ways to pass large structs for example by reference  
 in D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for reading  
 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

That sounds pretty reasonable, since I don't think anyone is using 'in' the way it is now. All in/out/inout could be documented as referencing, which makes them consistent.
May 25 2005
next sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
Is 'in' modifier passes struct by reference? 
May 25 2005
parent Vathix <vathix dprogramming.com> writes:
On Wed, 25 May 2005 12:35:49 -0400, Andrew Fedoniouk  
<news terrainformatica.com> wrote:

 Is 'in' modifier passes struct by reference?

Not right now, but that's what we're suggesting.
May 25 2005
prev sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Vathix wrote:
 That sounds pretty reasonable, since I don't think anyone is using 'in'  
 the way it is now.

I am... -- Chris Sauls
May 25 2005
parent reply imr1984 <imr1984_member pathlink.com> writes:
In article <d72kj0$9re$1 digitaldaemon.com>, Chris Sauls says...
Vathix wrote:
 That sounds pretty reasonable, since I don't think anyone is using 'in'  
 the way it is now.

I am... -- Chris Sauls

What exactly is your existing use for 'in' ?
May 25 2005
parent Chris Sauls <ibisbasenji gmail.com> writes:
imr1984 wrote:
 What exactly is your existing use for 'in' ?

I guess I just like to be explicit. And I do make healthy use of 'out' and 'inout' so in my desire for consistant coding style I also use explicit 'in' for completeness. -- Chris Sauls
May 25 2005
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
In article <d7276s$2vcl$1 digitaldaemon.com>, imr1984 says...
Ok im sorry to bring this up again, but Im still very peaved by this. At the
moment here are the ways to pass large structs for example by reference in D:

-use a pointer (*) 
-use inout
-use out 

None of these are acceptable for passing references that are for reading only.
The in keyword should be changed so that it passes by reference.

Why hasnt this problem been fixed?

D hass no concept of logical const-ness, which this requires. Sean
May 25 2005
prev sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"imr1984" <imr1984_member pathlink.com> wrote in message 
news:d7276s$2vcl$1 digitaldaemon.com...
 Ok im sorry to bring this up again, but Im still very peaved by this. At 
 the
 moment here are the ways to pass large structs for example by reference in 
 D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for reading 
 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

It would be a pretty big change in semantics. Passing by reference would mean it would have to be an lvalue. So one wouldn't be able to do something like struct Foo{ int x,y;} void bar(Foo a){ ... } Foo baz(){ ... } ... bar(baz()); Since structs are typically "lightweight" large structs will most likely be rare. What situation do you have where the struct is large? Also note that objects are passed by reference with 'in' and that doesn't stop someone from changing the object through the reference. I'm confused about exactly what you are proposing 'in' do.
May 25 2005
next sibling parent imr1984 <imr1984_member pathlink.com> writes:
In article <d72ad6$up$1 digitaldaemon.com>, Ben Hinkle says...
"imr1984" <imr1984_member pathlink.com> wrote in message 
news:d7276s$2vcl$1 digitaldaemon.com...
 Ok im sorry to bring this up again, but Im still very peaved by this. At 
 the
 moment here are the ways to pass large structs for example by reference in 
 D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for reading 
 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

It would be a pretty big change in semantics. Passing by reference would mean it would have to be an lvalue. So one wouldn't be able to do something like struct Foo{ int x,y;} void bar(Foo a){ ... } Foo baz(){ ... } ... bar(baz()); Since structs are typically "lightweight" large structs will most likely be rare. What situation do you have where the struct is large? Also note that objects are passed by reference with 'in' and that doesn't stop someone from changing the object through the reference. I'm confused about exactly what you are proposing 'in' do.

There are loads of situations when structs get large - a decent programming language should support this, and it shouldnt force the user into using classes.
May 25 2005
prev sibling parent reply imr1984 <imr1984_member pathlink.com> writes:
Im not talking about a particular struct *always* being passed by reference,
just sometimes by using the a "ref" keyword like C# does, or using a MODIFIED in
keyword. Walter is this ever going to change?

In article <d72ad6$up$1 digitaldaemon.com>, Ben Hinkle says...
"imr1984" <imr1984_member pathlink.com> wrote in message 
news:d7276s$2vcl$1 digitaldaemon.com...
 Ok im sorry to bring this up again, but Im still very peaved by this. At 
 the
 moment here are the ways to pass large structs for example by reference in 
 D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for reading 
 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

It would be a pretty big change in semantics. Passing by reference would mean it would have to be an lvalue. So one wouldn't be able to do something like struct Foo{ int x,y;} void bar(Foo a){ ... } Foo baz(){ ... } ... bar(baz()); Since structs are typically "lightweight" large structs will most likely be rare. What situation do you have where the struct is large? Also note that objects are passed by reference with 'in' and that doesn't stop someone from changing the object through the reference. I'm confused about exactly what you are proposing 'in' do.

May 25 2005
next sibling parent "Kris" <fu bar.com> writes:
Structs can be handily passed around, by reference, using an inout
declaration.

However, a big problem arises when you want to do this using const structs ~
clearly, a const struct instance cannot be written to, which is what inout
implies. There's no way around this, other than to make the struct non-const
or pass by value instead.

The implications are several, but here's two:

1) With the current syntax, D is highly unlikely to break into the
embedded-device market (easily the most prevalent computers on the planet).
Const is used there as a primary storage attribute, to place reference data
into ROM. It's easy to understand why once you've worked on devices with
just 4KB RAM, but lots of ROM. Accordingly, these devices also have tiny
stacks (often 256 bytes) so one requires the ability to pass structs by
reference instead of by value.

2) Read-only reference data should remain that way. By making it read/write,
one is losing a primary defence against certain kinds of bugs. D simply does
not support such things when it comes to structs passed by reference. This
weakens certain claims over language robustness.

- Kris


"imr1984" <imr1984_member pathlink.com> wrote in message
news:d72f1k$5om$1 digitaldaemon.com...
 Im not talking about a particular struct *always* being passed by

 just sometimes by using the a "ref" keyword like C# does, or using a

 keyword. Walter is this ever going to change?

 In article <d72ad6$up$1 digitaldaemon.com>, Ben Hinkle says...
"imr1984" <imr1984_member pathlink.com> wrote in message
news:d7276s$2vcl$1 digitaldaemon.com...
 Ok im sorry to bring this up again, but Im still very peaved by this.



 the
 moment here are the ways to pass large structs for example by reference



 D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for



 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

It would be a pretty big change in semantics. Passing by reference would mean it would have to be an lvalue. So one wouldn't be able to do


like
  struct Foo{ int x,y;}
  void bar(Foo a){ ... }
  Foo baz(){ ... }
  ...
  bar(baz());
Since structs are typically "lightweight" large structs will most likely


rare. What situation do you have where the struct is large?

Also note that objects are passed by reference with 'in' and that doesn't
stop someone from changing the object through the reference. I'm confused
about exactly what you are proposing 'in' do.


May 25 2005
prev sibling next sibling parent reply sam987883 yahoo.com writes:
Hi.  I'm a C#/java/C++ developer just learning about this D language.  One of
the things I liked most about C++ was the ability to pass variables by either
value or reference, regardless of whether they are a class or struct.  In fact,
the 'struct' keyword need not even exist in the C++ language, since the only
difference between it and a class is the default access modifiers (according to
Bjourne Stroustrup) (sp??).

Likewise, if D is to be an improvement over C++, then why is the 'struct'
keyword still around?  Why not give the option to the developer to pass objects
by value or by reference to methods?  AND, for that matter, why not do the same
for variable assignments?

Being a C++ developer, I would've liked to have seen this (what I consider to be
quite intuitive) operator syntax for variable assignments:

int i = 1, j = 2;
i = j; // Pass j to i by reference; i now points to what j points to or what j
is.
i << j; // Copy the contents of j (or pointed by j) to i
i >> j; // Copy the contents of i (or pointed by i) to j


I guess according to what I have above, this would also be nice:

int i << 2;
int j >> 3; //ERROR - can't change the value of a constant

Can someone tell me if pointer syntax is still used in D?
& - Address of  -or-  By reference
* - Indirection  -or-  Pointer declaration


How do I do these in D:

void f(const int& i) {}
void f(const int i) {}

I think this ties back to the argument of what the keyword "in" is suppose to
do.  Why lose such nice features of C++?  It's features like this that stop
programmers from doing something stupid, like modifying the value of i.  It's
also less overhead.


Single Inheritance???  WHY???  This is a mistake.  I think I'll wait for .NET
2.0 where C# will support generics and multiple inheritance.  I guess Microsoft
found a way around having multiple copies of the same base class in memory.

In article <d72f1k$5om$1 digitaldaemon.com>, imr1984 says...
Im not talking about a particular struct *always* being passed by reference,
just sometimes by using the a "ref" keyword like C# does, or using a MODIFIED in
keyword. Walter is this ever going to change?

In article <d72ad6$up$1 digitaldaemon.com>, Ben Hinkle says...
"imr1984" <imr1984_member pathlink.com> wrote in message 
news:d7276s$2vcl$1 digitaldaemon.com...
 Ok im sorry to bring this up again, but Im still very peaved by this. At 
 the
 moment here are the ways to pass large structs for example by reference in 
 D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for reading 
 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

It would be a pretty big change in semantics. Passing by reference would mean it would have to be an lvalue. So one wouldn't be able to do something like struct Foo{ int x,y;} void bar(Foo a){ ... } Foo baz(){ ... } ... bar(baz()); Since structs are typically "lightweight" large structs will most likely be rare. What situation do you have where the struct is large? Also note that objects are passed by reference with 'in' and that doesn't stop someone from changing the object through the reference. I'm confused about exactly what you are proposing 'in' do.


-Sam sam987883 yahoo.com
May 25 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 25 May 2005 21:16:46 +0000 (UTC), sam987883 yahoo.com wrote:

 Hi.  I'm a C#/java/C++ developer just learning about this D language.  One of
 the things I liked most about C++ was the ability to pass variables by either
 value or reference, regardless of whether they are a class or struct.  In fact,
 the 'struct' keyword need not even exist in the C++ language, since the only
 difference between it and a class is the default access modifiers (according to
 Bjourne Stroustrup) (sp??).
 
 Likewise, if D is to be an improvement over C++, then why is the 'struct'
 keyword still around?

Because in D, a class and a struct are not the same thing. A D struct is not the same as a C struct. This is something that C/C++ people need to learn. There are similarities, but there are also major differences. They serve different purposes. In general in D, if you need to pass things by reference one would use a class. If you need to pass things by value *by default* one would use a struct. You can override the default passing method for structs, but not for classes. Classes are always passed by reference. You can pass a struct by reference by passing its address. D does not support read-only items when they are passed by reference. I think this is because Walter believes that because it can never be absolutely guaranteed by the compiler, it should never be attempted by the compiler. It is up to the coder to preserve the integrity of 'read-only' classes, arrays, and structs passed by reference. [snip]
 Can someone tell me if pointer syntax is still used in D?
 & - Address of  -or-  By reference
 * - Indirection  -or-  Pointer declaration

Yes.
 How do I do these in D:
 
 void f(const int& i) {}
 void f(const int i) {}

void f(int* i) {} void f(int i) {} But the effect is different. In D, this does not produce compiler or runtime errors, instead it just preserves the value of the passed data. In the first case "void f(int* i) {}", and from the point of view of the calling routine, the address pointer to the integer is not modified by function. Even if the function does something like " i = 0; ", but note that this does not extend to the data pointed to by 'i'. That can be modified by the called function. If the caller absolutely must be sure that the data pointed to is not modified, then the caller needs to pass a (temporary) copy of the data. { int j = i; func(&j); assert( j == i); }
 I think this ties back to the argument of what the keyword "in" is suppose to
 do.  Why lose such nice features of C++?  It's features like this that stop
 programmers from doing something stupid, like modifying the value of i.  It's
 also less overhead.

Have a look at this. It explains what the 'in' attribute is doing. http://www.prowiki.org/wiki4d/wiki.cgi?FunctionParameterAttributes -- Derek Melbourne, Australia 26/05/2005 7:58:30 AM
May 25 2005
next sibling parent reply Sam <Sam_member pathlink.com> writes:
Very interesting!  I was just reading about D's asserts and invariant blocks!

Yeah, it's true that read-only parameters aren't really needed...  But I used
them so much!

Hey, speaking of read-only, in .NET's C# one could use the 'readonly' keyword on
member variables of a class/struct.  And it had the same effect as the 'final'
keyword in java, in that one could only change the value of those members in a
constructor.  After construction, those members are treated as 'const' and
cannot change.  This did not exist in C/C++.
Does this exist in D?  If so, what's the keyword for it?

Also, does the developer control the memory alignment of structs/unions and not
classes?

Do structs enjoy the same object-oriented features as classes in D, or are they
different?

Thanks! ;P

In article <1louv8ib995xo.ffsjmdaplh9i$.dlg 40tude.net>, Derek Parnell says...
On Wed, 25 May 2005 21:16:46 +0000 (UTC), sam987883 yahoo.com wrote:

 Hi.  I'm a C#/java/C++ developer just learning about this D language.  One of
 the things I liked most about C++ was the ability to pass variables by either
 value or reference, regardless of whether they are a class or struct.  In fact,
 the 'struct' keyword need not even exist in the C++ language, since the only
 difference between it and a class is the default access modifiers (according to
 Bjourne Stroustrup) (sp??).
 
 Likewise, if D is to be an improvement over C++, then why is the 'struct'
 keyword still around?

Because in D, a class and a struct are not the same thing. A D struct is not the same as a C struct. This is something that C/C++ people need to learn. There are similarities, but there are also major differences. They serve different purposes. In general in D, if you need to pass things by reference one would use a class. If you need to pass things by value *by default* one would use a struct. You can override the default passing method for structs, but not for classes. Classes are always passed by reference. You can pass a struct by reference by passing its address. D does not support read-only items when they are passed by reference. I think this is because Walter believes that because it can never be absolutely guaranteed by the compiler, it should never be attempted by the compiler. It is up to the coder to preserve the integrity of 'read-only' classes, arrays, and structs passed by reference. [snip]
 Can someone tell me if pointer syntax is still used in D?
 & - Address of  -or-  By reference
 * - Indirection  -or-  Pointer declaration

Yes.
 How do I do these in D:
 
 void f(const int& i) {}
 void f(const int i) {}

void f(int* i) {} void f(int i) {} But the effect is different. In D, this does not produce compiler or runtime errors, instead it just preserves the value of the passed data. In the first case "void f(int* i) {}", and from the point of view of the calling routine, the address pointer to the integer is not modified by function. Even if the function does something like " i = 0; ", but note that this does not extend to the data pointed to by 'i'. That can be modified by the called function. If the caller absolutely must be sure that the data pointed to is not modified, then the caller needs to pass a (temporary) copy of the data. { int j = i; func(&j); assert( j == i); }
 I think this ties back to the argument of what the keyword "in" is suppose to
 do.  Why lose such nice features of C++?  It's features like this that stop
 programmers from doing something stupid, like modifying the value of i.  It's
 also less overhead.

Have a look at this. It explains what the 'in' attribute is doing. http://www.prowiki.org/wiki4d/wiki.cgi?FunctionParameterAttributes -- Derek Melbourne, Australia 26/05/2005 7:58:30 AM

Sam- sam987883 yahoo.com
May 25 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 25 May 2005 22:30:29 +0000 (UTC), Sam wrote:

 Very interesting!  I was just reading about D's asserts and invariant blocks!

A very useful (read: cost saving) device.
 Yeah, it's true that read-only parameters aren't really needed...  But I used
 them so much!

By default, parameters are passed as 'in', thus making them read-only by default. But its the *parameter* that is read-only and not any data that the parameter refers to.
 Hey, speaking of read-only, in .NET's C# one could use the 'readonly' keyword
on
 member variables of a class/struct.  And it had the same effect as the 'final'
 keyword in java, in that one could only change the value of those members in a
 constructor.  After construction, those members are treated as 'const' and
 cannot change.  This did not exist in C/C++.
 Does this exist in D?  If so, what's the keyword for it?

No. A write-once item would be a nice thing to have. There would be some run-time overheads but for certain things it could be worth it.
 Also, does the developer control the memory alignment of structs/unions and not
 classes?

Correct.
 Do structs enjoy the same object-oriented features as classes in D, or are they
 different?

There are some differences. You can define member functions for structs, but you cannot define constructors or a destructor. You do not need to 'new' a struct, but you must 'new' a class. class Foo { } struct Bar { } Foo a = new Foo; // all classes live on the heap. Bar b; // created on the stack Bar* c = new Bar; // forced to live on the heap. You cannot base a struct on another via inheritance. You must include the base struct into the new struct. You cannot use Interfaces with a struct. struct Foo { . . . } struct Bar : Foo // illegal { . . . } struct Bar { Foo x; . . . } -- Derek Melbourne, Australia 26/05/2005 8:50:18 AM
May 25 2005
parent reply Sam <Sam_member pathlink.com> writes:
Wow!  It looks like D has really changed and enhanced structs and unions!  I'm
impressed!

Back to the 'readonly' or the write-once concept, you said it would be more
overhead to do this, but aren't virtual methods the same if not more overhead?
I wouldn't know as I'm not one of those low-level programmers...

Sam-
sam987883 yahoo.com
May 25 2005
parent Brad Beveridge <brad somewhere.net> writes:
Sam wrote:

 Back to the 'readonly' or the write-once concept, you said it would be more
 overhead to do this, but aren't virtual methods the same if not more overhead?
 I wouldn't know as I'm not one of those low-level programmers...
 
 Sam-
 sam987883 yahoo.com

You'd effectively have to wrap every member access in void memberSet(int value) if (firstAccess_memberName) memberName = value; else throw SomeException Although, if you wanted to be pretty clever, you could clump together all the "final" data into the same area, and allow writes to those memory pages during program startup, then mark that memory page as read-only. If anyone tries to write to the page the MMU would generate an exception. Of course it may not be good form for a general language to rely on potentially machine specific hardware features. Then you could have the write once feature, and the only overhead would be a small memory cost. Brad
May 25 2005
prev sibling parent Brad Beveridge <brad somewhere.net> writes:
Derek Parnell wrote:
<SNIP>
Likewise, if D is to be an improvement over C++, then why is the 'struct'
keyword still around?

Because in D, a class and a struct are not the same thing. A D struct is not the same as a C struct. This is something that C/C++ people need to learn. There are similarities, but there are also major differences. They serve different purposes. In general in D, if you need to pass things by reference one would use a class. If you need to pass things by value *by default* one would use a struct. You can override the default passing method for structs, but not for classes. Classes are always passed by reference. You can pass a struct by reference by passing its address. D does not support read-only items when they are passed by reference. I think this is because Walter believes that because it can never be absolutely guaranteed by the compiler, it should never be attempted by the compiler. It is up to the coder to preserve the integrity of 'read-only' classes, arrays, and structs passed by reference.

 [snip]

1) D structs are layed out the same as C structs, ie binary compatible. Which is required for interfacing to C code. D classes can re-arrange member order. 2) I primarily use structs for loading binary file formats. So I define a struct that matches the packing & member layout of the filetype I want to load, and then I just read a chunk of bytes into the struct from the file - perhaps doing further loading from there. 3) In embedded situations, structs are ideal for describing the layout of hardware. Brad
May 25 2005
prev sibling parent sam987883 yahoo.com writes:
Hi.  I'm a C#/java/C++ developer just learning about this D language.  One of
the things I liked most about C++ was the ability to pass variables by either
value or reference, regardless of whether they are a class or struct.  In fact,
the 'struct' keyword need not even exist in the C++ language, since the only
difference between it and a class is the default access modifiers (according to
Bjourne Stroustrup) (sp??).

Likewise, if D is to be an improvement over C++, then why is the 'struct'
keyword still around?  Why not give the option to the developer to pass objects
by value or by reference to methods?  AND, for that matter, why not do the same
for variable assignments?

Being a C++ developer, I would've liked to have seen this (what I consider to be
quite intuitive) operator syntax for variable assignments:

int i = 1, j = 2;
i = j; // Pass j to i by reference; i now points to what j points to or what j
is.
i << j; // Copy the contents of j (or pointed by j) to i
i >> j; // Copy the contents of i (or pointed by i) to j


I guess according to what I have above, this would also be nice:

int i << 2;
int j >> 3; //ERROR - can't change the value of a constant

Can someone tell me if pointer syntax is still used in D?
& - Address of  -or-  By reference
* - Indirection  -or-  Pointer declaration


How do I do these in D:

void f(const int& i) {}
void f(const int i) {}

I think this ties back to the argument of what the keyword "in" is suppose to
do.  Why lose such nice features of C++?  It's features like this that stop
programmers from doing something stupid, like modifying the value of i.  It's
also less overhead.


Single Inheritance???  WHY???  This is a mistake.  I think I'll wait for .NET
2.0 where C# will support generics and multiple inheritance.  I guess Microsoft
found a way around having multiple copies of the same base class in memory.

In article <d72f1k$5om$1 digitaldaemon.com>, imr1984 says...
Im not talking about a particular struct *always* being passed by reference,
just sometimes by using the a "ref" keyword like C# does, or using a MODIFIED in
keyword. Walter is this ever going to change?

In article <d72ad6$up$1 digitaldaemon.com>, Ben Hinkle says...
"imr1984" <imr1984_member pathlink.com> wrote in message 
news:d7276s$2vcl$1 digitaldaemon.com...
 Ok im sorry to bring this up again, but Im still very peaved by this. At 
 the
 moment here are the ways to pass large structs for example by reference in 
 D:

 -use a pointer (*)
 -use inout
 -use out

 None of these are acceptable for passing references that are for reading 
 only.
 The in keyword should be changed so that it passes by reference.

 Why hasnt this problem been fixed?

It would be a pretty big change in semantics. Passing by reference would mean it would have to be an lvalue. So one wouldn't be able to do something like struct Foo{ int x,y;} void bar(Foo a){ ... } Foo baz(){ ... } ... bar(baz()); Since structs are typically "lightweight" large structs will most likely be rare. What situation do you have where the struct is large? Also note that objects are passed by reference with 'in' and that doesn't stop someone from changing the object through the reference. I'm confused about exactly what you are proposing 'in' do.


-Sam sam987883 yahoo.com
May 25 2005