www.digitalmars.com         C & C++   DMDScript  

D - Pass by Reference? Pass by Value?

reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
I must have missed this in the documentation somewhere ... what is the
default argument passing convention for structs and classes? Presumably they
are both by reference?

I ask because it appears as though some of my structs are being passed by
value, and I can't change the argument type to 'inout' because the struct is
statically declared as a const ('inout' causes a compile error).

Any help would be much appreciated.

- Kris
Apr 21 2004
next sibling parent J Anderson <REMOVEanderson badmama.com.au> writes:
Kris wrote:

I must have missed this in the documentation somewhere ... what is the
default argument passing convention for structs and classes? Presumably they
are both by reference?

I ask because it appears as though some of my structs are being passed by
value, and I can't change the argument type to 'inout' because the struct is
statically declared as a const ('inout' causes a compile error).

Any help would be much appreciated.

- Kris

Default which is "in" works like a copy (by value) . Now *supposedly D will optimise the code if no copy is really needed*. For classes since they are really a pointer to a class the pointer is passed, so changes made to that class will effect the passed in one. -- -Anderson: http://badmama.com.au/~anderson/
Apr 21 2004
prev sibling parent reply "C. Sauls" <ibisbasenji yahoo.com> writes:
As J said, the default (in) is always pass-by-value (although it behaves 
like reference for classes, because of how they're stored).  You can 
always use a pointer... yes yes I know.  The function code would really 
work identically (since D does away with '->' syntax in favor of '.') 
but the caller would have to toss in the darn '&'... it'd work though. 
Or at least should.

-C. Sauls
-Invironz
Apr 21 2004
parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Thanks guys.

This identifies a syntactic weakness in D then, as Walter alluded to when he
wrote "It (perhaps?) eliminates the need for reference (&) declarations."
vis-a-vis 'out/inout' in the reference documentation.

One should presumably strive to avoid using pointers as arguments (unless
there's particular reason for doing so), so one would then move on to using
'inout' instead to force a call-by-reference. By doing so, the user is not
forced into thinking about '&' et. al. and all is indeed sweetness and
light.

However, you can't pass a struct as an 'inout' argument if it is declared
const, for obvious reasons. Therefore you either have to remove the const
declaration from the struct, or live with the pushing gobs of unnecessary
data onto the stack. Neither of these are appropriate long-term solutions.

This is hardly a showstopper, but it would be good to get it onto the list
for post-v1.0 fixes ...

Ideas? Walter?

- Kris



"C. Sauls" <ibisbasenji yahoo.com> wrote in message
news:c65ick$6ul$1 digitaldaemon.com...
 As J said, the default (in) is always pass-by-value (although it behaves
 like reference for classes, because of how they're stored).  You can
 always use a pointer... yes yes I know.  The function code would really
 work identically (since D does away with '->' syntax in favor of '.')
 but the caller would have to toss in the darn '&'... it'd work though.
 Or at least should.

 -C. Sauls
 -Invironz

Apr 21 2004
parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Kris wrote:

Thanks guys.

This identifies a syntactic weakness in D then, as Walter alluded to when he
wrote "It (perhaps?) eliminates the need for reference (&) declarations."
vis-a-vis 'out/inout' in the reference documentation.

One should presumably strive to avoid using pointers as arguments (unless
there's particular reason for doing so), so one would then move on to using
'inout' instead to force a call-by-reference. By doing so, the user is not
forced into thinking about '&' et. al. and all is indeed sweetness and
light.

However, you can't pass a struct as an 'inout' argument if it is declared
const, for obvious reasons. Therefore you either have to remove the const
declaration from the struct, or live with the pushing gobs of unnecessary
data onto the stack. Neither of these are appropriate long-term solutions.

This is hardly a showstopper, but it would be good to get it onto the list
for post-v1.0 fixes ...

Ideas? Walter?

- Kris
  

//module 1 template constArray(T) //This would be in another module { struct Array { private T [] array; static Array opCall(T [] array) { Array t; t.array = array; return t; } T opIndex(int i) { return array[i]; } int length() { return array.length; } } } alias constArray!(int).Array constA; //module 2 void test(constA array) { int x = array[0]; //You just can't change the array variable (well at least not without force). } void main() { int [] a; a ~= 10; a ~= 30; test(constA(a)); //Ok there's a small bit of extra typing -> if D only had automatic boxing.... } -- -Anderson: http://badmama.com.au/~anderson/
"C. Sauls" <ibisbasenji yahoo.com> wrote in message
news:c65ick$6ul$1 digitaldaemon.com...
  

As J said, the default (in) is always pass-by-value (although it behaves
like reference for classes, because of how they're stored).  You can
always use a pointer... yes yes I know.  The function code would really
work identically (since D does away with '->' syntax in favor of '.')
but the caller would have to toss in the darn '&'... it'd work though.
Or at least should.

-C. Sauls
-Invironz
    


-- -Anderson: http://badmama.com.au/~anderson/
Apr 21 2004
parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Forgive me Joel; I don't see a "const" keyword in your example, so I don't
see any kind of workaround. Perhaps I'm still asleep ...

- Kris


"J Anderson" <REMOVEanderson badmama.com.au> wrote in message
news:c66edq$1o48$1 digitaldaemon.com...
 Kris wrote:

Thanks guys.

This identifies a syntactic weakness in D then, as Walter alluded to when


wrote "It (perhaps?) eliminates the need for reference (&) declarations."
vis-a-vis 'out/inout' in the reference documentation.

One should presumably strive to avoid using pointers as arguments (unless
there's particular reason for doing so), so one would then move on to


'inout' instead to force a call-by-reference. By doing so, the user is


forced into thinking about '&' et. al. and all is indeed sweetness and
light.

However, you can't pass a struct as an 'inout' argument if it is declared
const, for obvious reasons. Therefore you either have to remove the const
declaration from the struct, or live with the pushing gobs of unnecessary
data onto the stack. Neither of these are appropriate long-term


This is hardly a showstopper, but it would be good to get it onto the


for post-v1.0 fixes ...

Ideas? Walter?

- Kris

//module 1 template constArray(T) //This would be in another module { struct Array { private T [] array; static Array opCall(T [] array) { Array t; t.array = array; return t; } T opIndex(int i) { return array[i]; } int length() { return array.length; } } } alias constArray!(int).Array constA; //module 2 void test(constA array) { int x = array[0]; //You just can't change the array variable (well at least not without force). } void main() { int [] a; a ~= 10; a ~= 30; test(constA(a)); //Ok there's a small bit of extra typing -> if D only had automatic boxing.... } -- -Anderson: http://badmama.com.au/~anderson/
"C. Sauls" <ibisbasenji yahoo.com> wrote in message
news:c65ick$6ul$1 digitaldaemon.com...


As J said, the default (in) is always pass-by-value (although it behaves
like reference for classes, because of how they're stored).  You can
always use a pointer... yes yes I know.  The function code would really
work identically (since D does away with '->' syntax in favor of '.')
but the caller would have to toss in the darn '&'... it'd work though.
Or at least should.

-C. Sauls
-Invironz


-- -Anderson: http://badmama.com.au/~anderson/

Apr 21 2004
parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Yep - I was asleep.  Thanks for the suggestion.

"Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
news:c66f83$1qhf$1 digitaldaemon.com...
 Forgive me Joel; I don't see a "const" keyword in your example, so I don't
 see any kind of workaround. Perhaps I'm still asleep ...

 - Kris


 "J Anderson" <REMOVEanderson badmama.com.au> wrote in message
 news:c66edq$1o48$1 digitaldaemon.com...
 Kris wrote:

Thanks guys.

This identifies a syntactic weakness in D then, as Walter alluded to



 he
wrote "It (perhaps?) eliminates the need for reference (&)



vis-a-vis 'out/inout' in the reference documentation.

One should presumably strive to avoid using pointers as arguments



there's particular reason for doing so), so one would then move on to


'inout' instead to force a call-by-reference. By doing so, the user is


forced into thinking about '&' et. al. and all is indeed sweetness and
light.

However, you can't pass a struct as an 'inout' argument if it is



const, for obvious reasons. Therefore you either have to remove the



declaration from the struct, or live with the pushing gobs of



data onto the stack. Neither of these are appropriate long-term


This is hardly a showstopper, but it would be good to get it onto the


for post-v1.0 fixes ...

Ideas? Walter?

- Kris

//module 1 template constArray(T) //This would be in another module { struct Array { private T [] array; static Array opCall(T [] array) { Array t; t.array = array; return t; } T opIndex(int i) { return array[i]; } int length() { return array.length; } } } alias constArray!(int).Array constA; //module 2 void test(constA array) { int x = array[0]; //You just can't change the array variable (well at least not without force). } void main() { int [] a; a ~= 10; a ~= 30; test(constA(a)); //Ok there's a small bit of extra typing -> if D only had automatic boxing.... } -- -Anderson: http://badmama.com.au/~anderson/
"C. Sauls" <ibisbasenji yahoo.com> wrote in message
news:c65ick$6ul$1 digitaldaemon.com...


As J said, the default (in) is always pass-by-value (although it




like reference for classes, because of how they're stored).  You can
always use a pointer... yes yes I know.  The function code would




work identically (since D does away with '->' syntax in favor of '.')
but the caller would have to toss in the darn '&'... it'd work though.
Or at least should.

-C. Sauls
-Invironz


-- -Anderson: http://badmama.com.au/~anderson/


Apr 21 2004
parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Kris wrote:

Yep - I was asleep.  Thanks for the suggestion.
  

it for classes (although probably not as neat). -- -Anderson: http://badmama.com.au/~anderson/
Apr 21 2004
parent "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
It was actually with structs. See the setStatus() method below.

// Status is a compound type, with a name and a code.
struct HttpStatus
{
        int     code;
        char[]  name;
}

// traditional response codes
enum HttpResponseCode
{
        Continue                     = 100,
        SwitchingProtocols      = 101,
        OK                             = 200,
        // etc ...
}

//Declare the traditional set of HTTP responses
struct HttpResponses
{
        // these should all be const ...
        static const HttpStatus Continue = {HttpResponseCode.Continue,
"Continue"};
        static const HttpStatus OK = {HttpResponseCode.OK, "OK"};
        // etc ...
}

// Argument status cannot be passed by inout-reference, cos' it's const
void setStatus (HttpStatus status)
{
                this.status = status;
}


- Kris



"J Anderson" <REMOVEanderson badmama.com.au> wrote in message
news:c66pam$2cab$3 digitaldaemon.com...
 Kris wrote:

Yep - I was asleep.  Thanks for the suggestion.

it for classes (although probably not as neat). -- -Anderson: http://badmama.com.au/~anderson/

Apr 21 2004