Jump to content
dummzeuch

for loop variable value after the loop

Recommended Posts

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
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
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
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
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

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.

  • Like 1
  • Thanks 1

Share this post


Link to post

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
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

  • Like 1

Share this post


Link to post
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

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 by dummzeuch
  • Like 2

Share this post


Link to post

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?

  • Like 1

Share this post


Link to post
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.

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×