Array as an argument, ambiguous behaviour.

Cooler kulkin at hotbox.ru
Thu Jan 30 06:07:14 PST 2014


On Thursday, 30 January 2014 at 13:44:39 UTC, Steven 
Schveighoffer wrote:
> kOn Wed, 29 Jan 2014 05:55:56 -0500, Cooler <kulkin at hotbox.ru> 
> wrote:
>
>> Consider 3 functions taking array as an argument:
>>
>> void fun1(in  int[] x){...}
>> void fun2(ref int[] x){...}
>> void fun3(    int[] x){...}
>>
>> auto a = new int[10];
>>
>> fun1(a); // Guaranteed that "a" will not be changed
>> fun2(a); // Guaranteed that we will see any change to "a", 
>> made in fun2()
>> fun3(a); // Changes to "a" in fun3() may be or may be not 
>> visible to the caller
>>
>> In case of fun3() we have ambiguous behaviour, depending on 
>> the body of the function.
>>
>> Am I right?
>
> Yes.
>
>> Is that intentional?
>
> Yes.
>
> I read the rest of the discussion. Arrays are hard to 
> understand in D, especially if you have preconceived notions 
> from other languages. But I would point out that fun2 does not 
> "guarantee" anything more than fun3:
>
> void fun2(ref int [] x)
> {
>    fun3(x);
> }
If I don't want that fun() will change my array, i have to use 
fun1() variant.
If I want fun() will change my array, i have to use fun2() 
variant. What fun2() do with it's argument inside it's body - not 
my business.

>
> It is an intrinsic property of slices that they do not own the 
> data pointed at. You cannot guarantee that one slice's changes 
> will affect another slice, AS LONG AS one slice is increasing 
> its length. If you avoid increasing the length, then the 
> results are deterministic. As I said in the article, avoid 
> increasing the length, and THEN changing the original data. If 
> you do that, you should have quite predictable results. If your 
> code must do otherwise, explain in the documentation what 
> should happen (i.e. don't use the passed-in slice after the 
> function), and use some of the tricks to avoid it (use ref, or 
> return the new slice data).
>
> -Steve

1. For example somebody already implemented fun1() and fun2() 
variants, as in my first post. This variants understandable and 
predictable. What can push me to ask another person for fun3() 
implementation, while it result is unpredictable, until you know 
fun3() body?

2. You wrote "If your code must do otherwise, explain in the 
documentation what
should happen". That exactly what I am trying to discuss here. 
Instead of writing some documentation, just warn (and may be 
prohibit in far-far future) about such possible unpredictability 
during compilation.


More information about the Digitalmars-d-learn mailing list