View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0038378||FPC||Compiler||public||2021-01-20 16:27||2021-01-21 16:42|
|Reporter||Klaus1||Assigned To||Jonas Maebe|
|Status||resolved||Resolution||no change required|
|Summary||0038378: For dyn. arrays as OUT paramter the function High (parameter) give -1 and not the correct dimension.|
|Description||For multi dimensional arrays as OUT parameter the function High give -1 as result and not the correct dimension.|
Use a VAR parameter with High the result is correct. OUT parameter with explicit array of double give the correxct value.
But declare T1Dim = array of double -> High give -1.
You can test it with the console program Fehlertest.lpr.
The compiler give a warning for managed parameter (fill with zeros) but the array dimension must correct given in the
|Tags||No tags attached.|
|Fixed in Revision|
Fehlertest.lpr (511 bytes)
program Fehlertest; type T2Dim = array of array of Double; T1Dim = array of Double; var A :T2Dim; B :T2Dim; C :array of Double; D :T1Dim; cc :Char; procedure Test(var A:T2Dim; out B :T2Dim; out C :array of Double; out D :T1Dim); var i,j,k,l :Integer; begin i := High(A); j := High(B); k := High(C); l := High(D); end; begin SetLength(A,2,2); SetLength(B,2,2); SetLength(C,2); SetLength(D,2); Test(A,B,C,D); read(cc); end.
Fehlertest.lpr (511 bytes)
||Managed out-parameters are not filled with zero, but they are re-initialised (https://www.freepascal.org/docs-html/current/ref/refsu65.html, at the bottom ). For dynamic arrays, this means they will become an empty array. You have to use var-parameters if you wish to keep their dimensions. This will indeed also keep the values in the array. If you want to clear those, you have to do it manually.|
Sorry but this link give an error "not found". But I think its not correct an out parameter with declaration (array of doble)
give exact the dimension, but an exoplicit defined T1Dim = array of double give -1 . It is not consistent.
(out C :array of Double) is open array declaration. Out is meaningless here.
I have analyzed the assembler output of the compiler for my test program.
- Parameter defined as OUT parameter for dynamic fields:
The pointer to the passed parameter is cleared if it was defined in the caller.
The procedure must define the dynamic field with SetLength.
The caller then gets the address passed back.
Here, the called procedure defines the output, the caller must then
query the field dimensionn and read the data.
- Parameter defined as OUT for open array (only defined for one-dimensional fields).
Here the field length is passed and the defined return field.
The caller tells the procedure where to output the data.
As normally expected, the caller controls the procedure.
Both approaches are completely different. The programmer normally expects
the caller to control the execution.
Therefore in the forums the many discussions. Also I understood this only by
the analysis of the assembler code. But this does not correspond to what is
described in the user manual. There it is stated that the procedure receives
the address of the output field and outputs the data there. The originally
there will be overwritten. Thus it is also clear that in the case of fields,
the field boundaries must be determinable in the procedure.
There is also another pitfall, what if when the procedure has defined the field
and then terminates due to an error -> memory leak?
|2021-01-20 16:27||Klaus1||New Issue|
|2021-01-20 16:27||Klaus1||File Added: Fehlertest.lpr|
|2021-01-20 16:35||Jonas Maebe||Assigned To||=> Jonas Maebe|
|2021-01-20 16:35||Jonas Maebe||Status||new => resolved|
|2021-01-20 16:35||Jonas Maebe||Resolution||open => no change required|
|2021-01-20 16:35||Jonas Maebe||FPCTarget||=> -|
|2021-01-20 16:35||Jonas Maebe||Note Added: 0128452|
|2021-01-21 13:53||Klaus1||Note Added: 0128459|
|2021-01-21 15:10||delfion||Note Added: 0128460|
|2021-01-21 16:42||Klaus1||Note Added: 0128462|