What should the following program do?
proc run() {
var A:[1..10] int;
foo(A[1..3]); // accepts argument with `in` and sets element 1
writeln("after foo, A[1] is ", A[1]); // is A[1] still 0?
}
proc foo(in A) {
writeln("in foo, chpl__isArrayView(A) is ", chpl__isArrayView(A));
writeln("in foo, A[1] is ", A[1]);
writeln("in foo, setting A[1] = 1");
A[1] = 1;
}
run();
In 1.16, it had the probably desired behavior described later (at the end A[1] is 0).
In 1.17 / 1.18 / 1.19 / 1.20, it gives C code compilation errors
In 1.21 / 1.22, this program core dumps
After that, as of 2ef4ab70de397a162ec68dbb50398bab608f45f3, it prints out
in foo, chpl__isArrayView(A) is true
in foo, A[1] is 0
in foo, setting A[1] = 1
after foo, A[1] is 1
Since in intent passing is similar to variable initialization, I would expect the in intent to copy the array view into a non-view array and as a result to print this:
in foo, chpl__isArrayView(A) is false
in foo, A[1] is 0
in foo, setting A[1] = 1
after foo, A[1] is 0
Here is a related example with tuples that appears to work the way I would expect:
var A:[1..10] int;
proc run() {
var A:[1..10] int;
foo( (A,A) );
writeln("after foo, A[1] is ", A[1]);
}
proc foo(in tup) {
writeln("in foo, tup(0)[1] is ", tup(0)[1]);
writeln("in foo, tup(1)[1] is ", tup(1)[1]);
writeln("in foo, setting A[1] = 1");
tup(0)[1] = 1;
writeln("in foo, tup(1)[1] is ", tup(1)[1]);
}
run();
My understanding of the in intent is that it makes "copy-in" of the actual argument (according to the docs page). If so, I think the code would behave equally as first making var Asub = A[1..3]; on the caller side and then passing Asub with the ref intent to foo(). Because var Asub = A[1..3]; makes a copy of the array value (rather than making a reference or making a copy of the "array descriptor"), I would also expect that foo( in A ) does not affect the original A on the caller side...
On the other hand, if foo() has the ref intent and is given an actual argument A[1..3], then I would expect foo() will receive an array view and the original A (on the caller side) to be modified.
@ty1027 beat me to it, but the final output in the OP is what I would expect as the output as well.
A.domain
Most helpful comment
My understanding of the
inintent is that it makes "copy-in" of the actual argument (according to the docs page). If so, I think the code would behave equally as first makingvar Asub = A[1..3];on the caller side and then passingAsubwith therefintent tofoo(). Becausevar Asub = A[1..3];makes a copy of the array value (rather than making a reference or making a copy of the "array descriptor"), I would also expect thatfoo( in A )does not affect the originalAon the caller side...On the other hand, if
foo()has therefintent and is given an actual argumentA[1..3], then I would expectfoo()will receive an array view and the originalA(on the caller side) to be modified.