Dave Novo 51 Posted June 21, 2020 I have a section of code where I need to modify the top record on a stack. This code is supposed to be highly performant, so I would like to optimize it as much as possible. I would like to get the top record of the stack without popping and pushing it. The record is somewhat complex, so copying the data back and forth to a temporary record is silly. A sample program is below type TMyRec=record s:string; end; PMyRec=^TMyrec; var stk:TStack<TMyRec>; rec:TMyRec; prec:pMyRec; begin stk:=TStack<TMyRec>.Create; rec.s:='Hello'; stk.push(rec); prec:=@stk.Peek; // get error “variable required” prec.s:=’Goodbye’; stk.Free; end; Seems like @stk.Peek is returning the address to the Peek method, not the pointer of the element being returned by the peek method. I have tried casting in various ways but it never compiles properly. Any ideas? Share this post Link to post
Mahdi Safsafi 225 Posted June 21, 2020 (edited) "@" operator requires a variable/constant/..., Here is your way : type PMyRec = ^TMyRec; TMyRec = record s: string; public function Address(): PMyRec; inline; end; var stk: TStack<TMyRec>; rec: TMyRec; prec: PMyRec; { TMyRec } function TMyRec.Address: PMyRec; begin Result := @Self; end; begin stk := TStack<TMyRec>.Create; rec.s := 'Hello'; stk.push(rec); prec := stk.Peek().Address(); Writeln(prec.s); prec.s := 'Goodbye'; stk.Free; end. Edited June 21, 2020 by Mahdi Safsafi 1 Share this post Link to post
Dave Novo 51 Posted June 21, 2020 @Mahdi Safsafi - thank you. Very clever! Share this post Link to post
David Heffernan 2345 Posted June 21, 2020 Surely that's just going to copy the record to a temp local, and return the address of that temp local. Or am I missing something? Share this post Link to post
Mahdi Safsafi 225 Posted June 21, 2020 22 minutes ago, David Heffernan said: Surely that's just going to copy the record to a temp local, and return the address of that temp local. Or am I missing something? Yes that's right. Share this post Link to post
Mahdi Safsafi 225 Posted June 21, 2020 @Dave Novo As David pointed out, you may need to use @stk.List[xxx]. Share this post Link to post
David Heffernan 2345 Posted June 21, 2020 (edited) 12 minutes ago, Mahdi Safsafi said: @Dave Novo As David pointed out, you may need to use @stk.List[xxx]. "may" is rather weak. A more detailed clarification may be useful to the asker, to make it clear that the code you offered does not prevent a copy, and in fact just adds obfuscation. However, it's also possible that there is premature optimisation going on here. Edited June 21, 2020 by David Heffernan Share this post Link to post
David Heffernan 2345 Posted June 21, 2020 19 minutes ago, Mahdi Safsafi said: use @stk.List[xxx] What value of xxx is to be used? Share this post Link to post
Mahdi Safsafi 225 Posted June 21, 2020 3 minutes ago, David Heffernan said: "may" is rather weak. A more detailed clarification may be useful to the asker, to make it clear that the code you offered does not prevent a copy, and in fact just adds obfuscation. However, it's also possible that there is premature optimisation going on here. He wrote "@stk.Peek" and I understood that he wanted the address of the peeked value. Share this post Link to post
Mahdi Safsafi 225 Posted June 21, 2020 4 minutes ago, David Heffernan said: What value of xxx is to be used? Hmmm that depends on him e.g : stk.count - 1 ; 0 ; 1 .... Share this post Link to post
David Heffernan 2345 Posted June 21, 2020 17 minutes ago, Mahdi Safsafi said: He wrote "@stk.Peek" and I understood that he wanted the address of the peeked value. No. It's clear. He wants the address of the record stored internally by the class to avoid a copy. Share this post Link to post
Dave Novo 51 Posted June 21, 2020 I wanted to modify the top record of the stack, without removing the record from the stack. Seems like with the way records work (copies all the time) that may not be possible with the current TStack implementation, given the intermediate records that are along the way. With our own structures, in situations that require it, we do take the effort to ensure there are no intermediate records and we get direct access to the address of the record we want to modify. I had not considered that the result of Peek would actually be a copy of the record at the top of the stack. Share this post Link to post
Mahdi Safsafi 225 Posted June 21, 2020 9 minutes ago, Dave Novo said: I wanted to modify the top record of the stack, without removing the record from the stack. Seems like with the way records work (copies all the time) that may not be possible with the current TStack implementation, given the intermediate records that are along the way. With our own structures, in situations that require it, we do take the effort to ensure there are no intermediate records and we get direct access to the address of the record we want to modify. I had not considered that the result of Peek would actually be a copy of the record at the top of the stack. My bad, I didn't understood you correctly. As I mentioned before, you can still use @stk.List[value] to get a pointer of your record without copying the data. Share this post Link to post
Dave Novo 51 Posted June 22, 2020 In Delphi Seattle, there is no List array property. The internal array is called FItems and it is Private. Share this post Link to post