inout/out static array parameter

Derek Parnell derek at psych.ward
Tue Feb 21 21:09:47 PST 2006


On Wed, 22 Feb 2006 17:16:30 +1300, Regan Heath wrote:

> On Wed, 22 Feb 2006 14:15:32 +1100, Derek Parnell <derek at psych.ward> wrote:
>> On Wed, 22 Feb 2006 03:02:22 +0000 (UTC), Tom wrote:
>>
>>> Why is this illegal? Where does the documentation states this?
>>> Does it have something to do with the matter that int[10] is allocated  
>>> onto the
>>> stack? Sometimes I think D losses its abstraction capability when one  
>>> has to be
>>> concerned about this kind of differences.
>>>
>>> 5# void f(inout int[10] x)
>>> 6# {
>>> 7# 	x[0..$] = 99;
>>> 8# }
>>>
>>> test.d(5): cannot have out or inout parameter of type int[10]
>>
>> I cannot see why D should be upset with this. The implementation would be
>> just be passing the address of the int[10] array, just as it does for  
>> 'in' parameters.
> 
> Not quite, when you pass something as 'in' you always get a copy of it,  
> this is true even for arrays. 

I don't believe that to be entirely accurate. For example, if you pass an
'int' as an 'in' parameter you get a 'mov EAX,<var>' generated, but if you
pass the same variable as an 'inout' you get a 'lea EAX,<var>' generated.
To me this is saying that whenever an 'inout' parameter is passed, it is
the actual address of that parameter passed. Even when the variable is a
class instance. In that case an 'in' parameter gets the value of the object
reference and an 'inout' gets the address of the object reference. The same
with variable-length arrays. However when we get to fixed length arrays,
the 'in/inout/out' regime is gets fubar'ed. You can pass a fixed-length
array with an 'in' parameter and what get's passed is the address of the
first item in the array - which means that the function is free to modify
the contents (yes it is an 'in' parameter) but of course the address of the
data is not changed (that's what 'in' is really protecting). So in effect,
for fixed-length arrays, 'in' and 'inout' are synonymous. Which is not what
a normal person would guess. So why not allow 'inout' with fixed-length
arrays? Isn't this how a coder would tell the reader that he *intends* to
change the passed array's data and 'in' is telling the reader that the
coder does NOT intend to change the data. 

> The important thing to realise is exactly  
> what it's passing/copying.
> 
> In this case:
> 
> int[10] data;
> void foo(int[10] a) {}
> foo(data);
> 
> You're passing a pointer to the array data, 'in' copies that pointer and  
> passes the copy.

It doesn't actually copy the pointer, it just passes the address of the
data  ("lea EAX,-8[EBP]").

> In this case:
> 
> int[10] data;
> void foo(inout int[10] a) {}
> foo(data);
> 
> You're not passing a copy of the pointer to the array data, you're passing  
> the actual pointer. 

No, that's what 'in' does.

>As we all know static/fixed arrays have a fixed data  
> pointer which cannot be assigned to or changed in any way. Therefore it's  
> illegal to pass that pointer as 'inout'.

Yes, I can see the logic of this, given that 'in' is designed to protect
the reference to the data and not the data itself. To have 'inout' in this
context would imply that the coder is trying to change the address of the
data and that is obviously not allowed.

This fundamental principle of D is not explained well enough in the
documentation. 

'in' protects that data passed to the function such that any change that
the function performs on the passed data, is not passed back to the calling
code.
   For fixed-length arrays the data is the address of first element
   For variable-length arrays the data is the length of the array
         and address of the the first element
   For objects the data is the object reference
   For structs thee data is the address of the struct contents
   For intrinsic items the data is the value of the variable.
 
>> In conceptual terms, it is identical to this, which D does
>> allow ...
>>
>> struct X
>> {
>>     int[10] x;
>> }
>> void f(inout X q)
>> {
>> 	q.x[0..$] = 99;
>> }
> 
> I think it depends on what "conceptual" really means in this case, in  
> terms of "how it works"(TM) I think it's closer to this:

No, I wasn't thinking "implementation" I was thinking "common sense".

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocracy!"
22/02/2006 3:31:20 PM



More information about the Digitalmars-d mailing list