Forum > General
Questions about initialization
Okoba:
I have a couple of questions and confusions around initialization and I appreciate any help for clarifying them.
Question1:
I always faced this one, but never find out why.
Considering these two Tests:
Test1:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; var A: array[0..10] of integer; I: integer;begin for I := 0 to High(A) do WriteLn(A[I]); ReadLn;end.
Test2:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; procedure Test; var A: array[0..10] of integer; I: integer; begin for I := 0 to High(A) do WriteLn(A[I]); end; begin Test; ReadLn;
Why in Test1, (as far as I know), A is zeroed, but not in Test2?
In both cases FPC warns about not initialized value.
Question2:
Why Initialize(A); does not zero the array?
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- procedure Test; var A: array[0..10] of integer; I: integer; begin Initialize(A); for I := 0 to High(A) do WriteLn(A[I]); end; For example if I use Initialize on a record, it will zero any value in it, but not for arrays. And it is documented as "Initializing means zeroing out the memory area".
What is the logic behind this?
I guess, one can say, it does Initialize the memory of array, but not the induvial items, but the array in it self is a type, so why not Initializing (zeroing out) it too?
Question3:
And to add to confusion of myself, Initialize is documented as "In this sense it is close in functionality to Default, but Default requires an already initialized variable."
But if I try to do this, I will get a zeroed array, so they are not the same.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- procedure Test; type TA = array[0..10] of integer; var A: TA; I: integer; begin A := Default(TA); for I := 0 to High(A) do WriteLn(A[I]); end;
Question4:
As said in documentation, "Default requires an already initialized variable." What does it mean? Is it best practice to call Initialize first and then Default?
Considering this sample:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; {$mode delphi}type { TTest } TTest = record I: integer; class operator Initialize(var AValue: TTest); class operator Finalize(var AValue: TTest); class operator AddRef(var AValue: TTest); class operator Copy(constref A: TTest; var B: TTest); end; class operator TTest.Initialize(var AValue: TTest); begin WriteLn('Initialize: ', QWord(@AValue)); end; class operator TTest.Finalize(var AValue: TTest); begin WriteLn('Finalize: ', QWord(@AValue)); end; class operator TTest.AddRef(var AValue: TTest); begin WriteLn('AddRef: ', QWord(@AValue)); end; class operator TTest.Copy(constref A: TTest; var B: TTest); begin WriteLn('Copy: ', QWord(@A), ' : ', QWord(@B)); end; procedure Test1; var V: TTest; begin end; procedure Test2; var V: TTest; begin Initialize(V); end; procedure Test3; var V: TTest; begin V := Default(TTest); end; begin WriteLn('Test1'); Test1; //No Initialize WriteLn('Test2'); Test2; //Two Initialize on same pointer! WriteLn('Test3'); Test3; //One Initialize ReadLn; //Log: //Test1 //Test2 //Initialize: 20971068 //Initialize: 20971068 //Finalize: 20971068 //Test3 //Initialize: 20971068 //Copy: 20971064 : 20971068 //Finalize: 20971068end.
Question5:
Why Test2 is initialize V two times for the same pointer?
Question6:
At Test3, Pointer 20971068 is initialized, but not 20971064. But FPC copies 20971064 to 20971068. Why? and how should I manage it to not duplicated a cost of copy? I thought Default, makes the value default, but it seem it makes a initialized(!) value and copy it to the variant.
Documentation of initialize: https://www.freepascal.org/docs-html/rtl/system/initialize.html
For future readers:
https://forum.lazarus.freepascal.org/index.php/topic,62706.msg474502.html#msg474502
speter:
Q1: I believe local variables are not initialised.
see https://www.freepascal.org/docs-html/ref/refse24.html
Q2: initialize() works on managed types, which I believe your array is not.
https://www.freepascal.org/docs-html/rtl/system/initialize.html
Q3: default() is the way to go :)
Q4: default's documentation (link below); does not say that default "requires an already initialized variable". I don't know why initialize's docs say that, it doesn't make any sense to me.
https://www.freepascal.org/docs-html/rtl/system/default.html
cheers
S.
howardpc:
The docs could have been more specific about Initialize and Finalize applying to managed variable types only.
For instance the pseudo signature could have been given as:
procedure Initialize( var T: TAnyManagedType; ACount: SizeInt = 1);
Thaddy:
@4: fixed length arrays are an exception: you can call default() on it.
There is one caveat: you need to provide a type for the fixed length array.
E.g:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$mode objfpc}{$H+}{$ifdef mswindows}{$apptype console}{$endif}procedure test;type TMyArray= array[0..9] of integer; // default() needs a typevar a:TMyArray; i:integer;begin for i in a do write(i,' ');writeln;// stack is dirty, array may contain random values a:=Default(TMyArray); // clean the static array writeln('==========================================='); for i in a do write(i,' ');writeln; //array contains only zero'send; begin test; readln;end.
Example output (different for every run):
--- Code: ---4194304 0 0 0 1 0 503 0 41120 1
===========================================
0 0 0 0 0 0 0 0 0 0
--- End code ---
So the documentation for Initialize() is wrong.It should read: "an initialized variable or a type.".
As long there is a type, default will work happily.
MarkMLl:
--- Quote from: speter on January 07, 2023, 08:30:38 am ---Q1: I believe local variables are not initialised.
see https://www.freepascal.org/docs-html/ref/refse24.html
--- End quote ---
i.e. Local variables are on the stack, which is reused repeatedly hence might contain stale data.
Global variables might (depending on implementation details) be in a separate global space or might get the first bit of stack.
In the general case, it might be best not to assume that this is initialised: a great deal depends on the language implementation, the linker, and the behaviour of the OS when it allocates and loads initial memory.
MarkMLl
Navigation
[0] Message Index
[#] Next page