dummzeuch 1529 Posted December 7, 2024 I just came across this code: var I: Integer; begin for I := 0 to Collection.Count - 1 do if TListColumn(Collection.Items[I]).WidthType <= ColumnTextWidth then Break; Changed(I <> Collection.Count); WriteCols; end; Is it just me or does anybody else think this is wrong? Or is the value of a for loop variable after a loop explicitly defined nowadays? I always thought that's compiler dependent and should not be relied on. Share this post Link to post
Cristian Peța 108 Posted December 7, 2024 https://docwiki.embarcadero.com/RADStudio/Athens/en/W1037_FOR-Loop_variable_'%s'_may_be_undefined_after_loop_(Delphi) 1 Share this post Link to post
DelphiUdIT 200 Posted December 7, 2024 23 minutes ago, dummzeuch said: Or is the value of a for loop variable after a loop explicitly defined nowadays? I always thought that's compiler dependent and should not be relied on. Me too thought that. And it's for this that I start using inline variable, sò no one can use the "index" outside the loop. Bye Share this post Link to post
dummzeuch 1529 Posted December 7, 2024 OK, so that's a bug in the VCL code then. Share this post Link to post
DelphiUdIT 200 Posted December 7, 2024 Just now, dummzeuch said: OK, so that's a bug in the VCL code then. And where exactly? It would be useful to know... Share this post Link to post
dummzeuch 1529 Posted December 7, 2024 34 minutes ago, DelphiUdIT said: And where exactly? It would be useful to know... Delphi 12, unit VCL.ComCtrls, method TListColumn.DoChange, line 17287. Probably also in older Delphi versions, I haven't checked. This didn't cause my actual problem though, because it works, even though it is undocumented behavior. Unfortunately I haven't found the cause, just a workaround, but that's enough for now. Share this post Link to post
Remy Lebeau 1461 Posted December 7, 2024 4 hours ago, dummzeuch said: Delphi 12, unit VCL.ComCtrls, method TListColumn.DoChange, line 17287. Probably also in older Delphi versions, I haven't checked. I just now checked, this code exists in TListColumn.DoChange() all the way back to at least Delphi 5 (that the oldest version I have VCL source code for)! Share this post Link to post
Cristian Peța 108 Posted December 8, 2024 I think this should be reported. Something like this I discovered in FastReport and it surfaced in rare circumstances. First when I reported it was ignored till I come with a case to reproduce. Because this, the report should have also the link to documentation. 1 1 Share this post Link to post
eivindbakkestuen 47 Posted December 8, 2024 It is a documentation omission, the help on the link states "You can only rely on the final value of a for loop control variable if the loop is left with a goto or exit statement. " In https://docwiki.embarcadero.com/RADStudio/Athens/en/Declarations_and_Statements_(Delphi)#For_Statements it says "After the for statement terminates (provided this was not forced by a Break or an Exit procedure), the value of counter is undefined. " The value should be defined, as the loop here exits with a Break, Share this post Link to post
David Heffernan 2357 Posted December 8, 2024 8 minutes ago, eivindbakkestuen said: The value should be defined, as the loop here exits with a Break, Doesn't always exit with a Break 1 Share this post Link to post
Patrick PREMARTIN 90 Posted December 9, 2024 On 12/7/2024 at 3:51 PM, dummzeuch said: I just came across this code: var I: Integer; begin for I := 0 to Collection.Count - 1 do if TListColumn(Collection.Items[I]).WidthType <= ColumnTextWidth then Break; Changed(I <> Collection.Count); WriteCols; end; Is it just me or does anybody else think this is wrong? Or is the value of a for loop variable after a loop explicitly defined nowadays? I always thought that's compiler dependent and should not be relied on. "I" is a variable. Its value is known during and after the loop. It's not a good way to write code but it's not wrong. The "for" loop can be seen as a "while I<=LastValue" with a "inc". It's a reason why so many developers wanted the "for var" syntax. Share this post Link to post
dummzeuch 1529 Posted December 9, 2024 (edited) A for loop is not a while loop with inc. the compiler might create code that counts down to zero rather than up, if the variable is not used inside the loop. Edit: Or it might even completely unroll the loop doing away with the variable altogether. But it does not matter: Relying on an undocumented implementation detail is a bad idea, regardless of whether it works or not. The next compiler version or a different compiler e.g. for a different platform might change that detail. Edited December 9, 2024 by dummzeuch 2 Share this post Link to post
Remy Lebeau 1461 Posted December 9, 2024 W1037 FOR-Loop variable '%s' may be undefined after loop (Delphi) Quote This warning is issued if the value of a for loop control variable is used after the loop. You can only rely on the final value of a for loop control variable if the loop is left with a goto or exit statement. The purpose of this restriction is to enable the compiler to generate efficient code for the for loop. Also see: What is The Loop Variable After a For Loop in Delphi? 1 Share this post Link to post
Brandon Staggs 303 Posted December 9, 2024 On 12/7/2024 at 8:51 AM, dummzeuch said: I just came across this code: var I: Integer; begin for I := 0 to Collection.Count - 1 do if TListColumn(Collection.Items[I]).WidthType <= ColumnTextWidth then Break; Changed(I <> Collection.Count); WriteCols; end; Is it just me or does anybody else think this is wrong? Or is the value of a for loop variable after a loop explicitly defined nowadays? I always thought that's compiler dependent and should not be relied on. Not just you. Regardless of the variable state at the end of the for loop, a while or repeat loop would be far more clear IMO. 1 Share this post Link to post