It is a quite neat trick if it is legal. (that self of a nested record points to the nested record, not the encompassing one)Although how could a nested Self point to anything else? It has no knowledge of being nested, it knows only itself.
It is a quite neat trick if it is legal. (that self of a nested record points to the nested record, not the encompassing one)
In any case, if you were to have a record with the last valid field being the same type as the empty array you can pull this trick which also works.This only works for non managed types. Managed types like strings can not occur in the variant parts of a record. But yes, in this case, it would be possible without requireing a function.
I have some doubts about the sizeof(self) (always pointer size =4/8 or nested record size=0?)This is actually quite a good question. The pointer size does not really matter but the record size does. I think that with packed it should always be 0 but I am not sure if this is the case and/or is documented somewhere.
This only works for non managed types. Managed types like strings can not occur in the variant parts of a record. But yes, in this case, it would be possible without requireing a function.
This all works fine with delphi, it's an old project.
procedure TForm1.Button1Click(Sender: TObject); Var T:PMyIntBaseRecord; begin T := GetMem(SizeOf(T)+SizeOf(integer)); {Create an item plus one integer at end} T^.IntCount := $FFFFFFFF; T^.Ints[0]:= 1; Caption := T^.IntCount.ToHexString+','+T^.ints[0].Tostring; FreeMem(T); end;
It is a quite neat trick if it is legal. (that self of a nested record points to the nested record, not the encompassing one)
I would hope it would be legal, I've doing such tricks for some time now and the SELF. It would be broken if not pointing to the immediate record when referenced which btw is also part of the parent record that over hangs at the end. That is the intent here.
I've found another solution that does not throw warnings and requires less code:
But compiling this let's the FPC enter an infinite loop with 100% CPU usage so. This is probably a bug in the FPC
I have some doubts about the sizeof(self) (always pointer size =4/8 or nested record size=0?)This is actually quite a good question. The pointer size does not really matter but the record size does. I think that with packed it should always be 0 but I am not sure if this is the case and/or is documented somewhere.
One exception I could think of is, when more advanced RTTI comes, that records might get hidden RTTI fields added if enabled. But TBH I don't know how the plans are for RTTI in advanced records
I assume you mean SizeOf(TMyIntBaseRecord) + SizeOf(Integer) instead of SizeOf(P) as otherwise you might get a nasty surprise on 32-bit systems ;)
If one writes the record once as a generic one can easily reuse it (and maybe we should even add this to the RTL... :-X ):
Why? Could you explain?If one writes the record once as a generic one can easily reuse it (and maybe we should even add this to the RTL... :-X ):
That was what I thinking too, not in the RTL, but in my own root record. (Records because they are opengl vertex buffers)
You're not going to initialize memory for each element. If you want that, use a linked list instead.Initialize is always called on each element, just normally it is hidden by compiler magic. TList from Generics.Collections for example uses "array of T" and allocates the memory with Setlength, which will internally call Initialize for each element.
Or is this to have the memory footprint of a C-struct:
struct SomeArray { int Length; int* Elements; };
Like Pascal strings/arrays?
Playing with the Generic's sample that Pascal posted it compiles etc but it does not INLINE.
do it without generics and it does inline.
I did this on 3.0.4 fpc so I don't know if higher levels have fixed this ?
For now I will stick with non generics because I don't want the calls for the setter and getter...