>Gesendet: Samstag, 30. Juni 2018 um 10:54 Uhr >Von: "Michael Van Canneyt" <mich...@freepascal.org> >> Am 30.06.2018 um 08:47 schrieb Sven Barth via fpc-devel: >>> The variables we're talking about here *are* initialized. >
Bit lost here. Maybe A and B are setup, but not result. And the apparent re-use of tmp vars also seems wrong. In the first call you get a "setup" var, in the second call an "initialized" one with previous values. But the latter is not commonly referred to as initialization, as initialization means usually setting to a sensible default value, which always is the same. >> Maybe the term initialized is wrong and confusing. They are not initialized >> in the sense of having defined values as >> global variables have. Non-global managed types should not be considered as >> being initialized (never!, like any other >> type), this is also why the compiler warns (!) about this. They can be >> considered as being "setup" by the compiler. So what does setup do - allocate memory and set refcount accordingly? If result was being setup properly that might also help. >>> They contain valid values and none of the internal RTL >>> routines will crash when used with them. Everyone however expects result >> variables of those to be initialized to Nil and >>> that is simply *not* a guaranteed given. I'd say if everyone expects that then there is a point in that the current behaviour is surprising and not intuitive. I mean, the compiler is for people, right? ;) >>> Also records only initialize their managed fields. All others are left as >> garbage. >> I'm only talking about managed types. > >> Managed fields of records are "setup" ;) > >I will add a section about this in the documentation, seeing that people >often confuse the 2 concepts. In an ideal world, either the language would not let you write code that has random behavior or the compiler would enforce this. Out of curiosity I did a couple of more tests and it seems FPC is pretty inconsistent in handling all this. See below. //... some form in lazarus with a tmemo and a button on it TCArray = array of integer; TMRecord = record arr: TCArray; end; // global vars var A, B: TCArray; C, D: TMRecord; function X(l:integer): TCArray; begin setlength(result,l); end; function Y(l: integer): TMRecord; begin setlength(result.arr, l); end; procedure global(memo1: TMemo); begin A:=X(3); A[0] := 5; A[1] := 4; B:=X(3); // the following will print 5 twice memo1.lines.add('GlobalA0: %d',[A[0]]); memo1.lines.add('GlobalB0: %d',[B[0]]); C := Y(3); C.arr[0] := 5; C.arr[1] := 4; D := Y(3); // the following will print 5 and 0 memo1.lines.add('GlobalC0: %d',[C.arr[0]]); memo1.lines.add('GlobalD0: %d',[D.arr[0]]); end; { TForm1 } // will add the following lines to memo1: //GlobalA0: 5 //GlobalB0: 5 (this is the strange case...) //GlobalC0: 5 //GlobalD0: 0 //LocalA0: 5 //LocalB0: 0 //LocalC0: 5 //LocalD0: 0 procedure TForm1.ToggleBox1Change(Sender: TObject); var A, B: TCArray; C, D: TMRecord; begin global(memo1); A:=X(3); A[0] := 5; A[1] := 4; B:=X(3); // the following will print 5 and 0 memo1.lines.add('LocalA0: %d',[A[0]]); memo1.lines.add('LocalB0: %d',[B[0]]); C := Y(3); C.arr[0] := 5; C.arr[1] := 4; D := Y(3); // the following will print 5 and 0 memo1.lines.add('LocalC0: %d',[C.arr[0]]); memo1.lines.add('LocalD0: %d',[D.arr[0]]); end; ... And at least with my current settings in Lazarus (standard ones) I don't see any warning about me venturing into the fields of undefined - or - random. Best, Willibald _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel