www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Modifiable typesafe variadic arguments

reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Trying to do something like this doesn't work:

void foo(int[] arr...) {
	for (int i = 0; i < arr.length; ++i)
		arr[i] = 3;
}

foo(x, y, z);

The variables passed retain their original values. Defining arr as inout or out
doesn't work, since that would be modifying the array reference, and as such the
compiler doesn't allow it.

Is there any way of doing it other than using pointers, like in the following?

void foo(int*[] arr...) {
	for (int i = 0; i < arr.length; ++i)
		*arr[i] = 3;
}

foo(&x, &y, &z);

My guess is there isn't, since std.stream.InputStream.readf, for instance, uses
pointers for this as well. Any ideas?
Jun 15 2006
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Deewiant wrote:
 Trying to do something like this doesn't work:
 
 void foo(int[] arr...) {
 	for (int i = 0; i < arr.length; ++i)
 		arr[i] = 3;
 }
 
 foo(x, y, z);
 
 The variables passed retain their original values. Defining arr as inout or out
 doesn't work, since that would be modifying the array reference, and as such
the
 compiler doesn't allow it.
 
 Is there any way of doing it other than using pointers, like in the following?
 
 void foo(int*[] arr...) {
 	for (int i = 0; i < arr.length; ++i)
 		*arr[i] = 3;
 }
 
 foo(&x, &y, &z);
 
 My guess is there isn't, since std.stream.InputStream.readf, for instance, uses
 pointers for this as well. Any ideas?

Not that I can find after a quick squiz at the docs. Honestly, I think that when you ever pass something to a function that it can change, there should be some explicit notice of this (like having to pass the argument by address). Well, ok, you could always play the "write a template for every possible argument length and use THAT to pass the arguments by address to the *real* function", but I think that's probably unnecessary :) -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 15 2006
parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Daniel Keep wrote:
 Honestly, I think that when you ever pass something to a function that it can
 change, there should be some explicit notice of this (like having to pass the
 argument by address).

I agree. Hence I still hope for my suggestion (which was originally someone else's idea, but I wrote it up at the D wish list, http://all-technology.com/eigenpolls/dwishlist/ ) requesting usage of explicit out/inout when calling to be implemented. Meaning, whenever you call a function with out/inout arguments, you specify out/inout at the call point as well as at the function definition.
 Well, ok, you could always play the "write a template for every possible
 argument length and use THAT to pass the arguments by address to the
 *real* function", but I think that's probably unnecessary :)
 
 	-- Daniel
 

Of course, and I think that's unnecessary as well, not to mention somewhat tedious. ;-)
Jun 15 2006
parent reply BCS <BCS pathlink.com> writes:
Deewiant wrote:
 Daniel Keep wrote:
 
Honestly, I think that when you ever pass something to a function that it can
change, there should be some explicit notice of this (like having to pass the
argument by address).

I agree. Hence I still hope for my suggestion (which was originally someone else's idea, but I wrote it up at the D wish list, http://all-technology.com/eigenpolls/dwishlist/ ) requesting usage of explicit out/inout when calling to be implemented. Meaning, whenever you call a function with out/inout arguments, you specify out/inout at the call point as well as at the function definition.

or a dummy for an out? this would be the effect, but its a bit verbose. int foo(inout int i, out int j) { j = i; i = 1; return i+j; } ... int i=1, k; ... { // don't care about i or j's returned value; int i_ = i, j_; k = foo(i_, j_); } ... something like this would be nice: ... int i=1, k; ... k = foo(i.dup, auto); ...
Jun 15 2006
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
BCS wrote:
 Deewiant wrote:
 Daniel Keep wrote:

 Honestly, I think that when you ever pass something to a function
 that it can
 change, there should be some explicit notice of this (like having to
 pass the
 argument by address).

I agree. Hence I still hope for my suggestion (which was originally someone else's idea, but I wrote it up at the D wish list, http://all-technology.com/eigenpolls/dwishlist/ ) requesting usage of explicit out/inout when calling to be implemented. Meaning, whenever you call a function with out/inout arguments, you specify out/inout at the call point as well as at the function definition.

or a dummy for an out? this would be the effect, but its a bit verbose. int foo(inout int i, out int j) { j = i; i = 1; return i+j; } ... int i=1, k; ... { // don't care about i or j's returned value; int i_ = i, j_; k = foo(i_, j_); } ... something like this would be nice: ... int i=1, k; ... k = foo(i.dup, auto); ...

Or you could do what Visual Basic did: allow the programmer to pass an immediate value as an 'inout' or 'out' parameter: in which case, it stores the immediate value somewhere, calls the function, then discards the value. I've always found it somewhat amusing that VB is the only language I've ever seen that allowed this nice little shortcut. I can't decide if that's because it's a bad idea, or because it's just really hard to do. Knowing VB, it's probably the former. -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 16 2006