Modifying nested lists/arrays in function changes variable in calling scope
Reported by Arvid
// =============================================================================
// << BUG REPORT >>
//
// Description:
//
// We have found a case where Scilab6 does not seem to handle scopes correctly.
// There seems to be an issue if nestled lists (at least two indices) where the
// elements have member variables are sent as arguments to functions. The
// variable sent to the function does not seem to be copied to a local function
// properly, so the variable sent to the function is directly modified.
//
// Below is a test case where this bug is exposed, and below that I have
// described my findings regarding the behavior of the bug.
//
// =============================================================================
// -----------------------------------------------------------------------------
// Test Case: 2D array with element member (which is a scalar)
// -----------------------------------------------------------------------------
// Define variables
testArray = list();
for i=1:1:10
testArray($+1) = list();
for j=1:1:10
testArray(i)($+1) = [];
testArray(i)(j).testMember = 1;
end
end
testArrayOrig = testArray;
// Define functions
function outArray = testFunc(inArray)
for i=1:1:10
for j=1:1:10
inArray(i)(j).testMember = 5
end
end
outArray = inArray;
endfunction
// Send the variable as argument to the function
if %t
testArrayOut = testFunc2(testArray);
if testArrayOut(1)(1).testMember == testArray(1)(1).testMember
error("Error! inputArgument was changed by function");
end
end
// -----------------------------------------------------------------------------
// FINDINGS
// -----------------------------------------------------------------------------
//
// The problems seems to occur when we have nestled lists (at least two indices)
// where the elements have their own members. The case that triggered us to
// investigate this bug used lists as members, but they can apparently also
// just be scalars.
//
// The bug occurs only when the value is written directly to the member.
// eg.
// * inArray(i)(j).testMember = 5
// writing to the element does not expose the bug
// eg.
// * dummyVariable.testMember = 5;
// inArray(i)(j) = dummyVariable
//
// What's even more weird is that when the bug occurs, all variables which are
// previously set equal to the input variable are also modified (in this example
// code I refer to these variables with the "Orig" suffix).
//
// -----------------------------------------------------------------------------