Recent

Author Topic: Iterator on non-existing structure  (Read 1892 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 5870
  • Compiler Developer
Re: Iterator on non-existing structure
« Reply #15 on: January 16, 2025, 09:01:07 pm »
Well the fix would actually be quite trivial:
Code: Pascal  [Select][+][-]
  1. function TFPGListEnumerator.MoveNext: Boolean;
  2. begin
  3.   if not assigned(FList) then
  4.     Exit(False);
  5.   inc(FPosition);
  6.   Result := FPosition < FList.Count;
  7. end;  

This would not help if the list itself from which the operator is queried is Nil which is what the question is about. The only solution - as Martin_fr had written - would be to check Self in TFPGList.GetEnumerator.

Warfley

  • Hero Member
  • *****
  • Posts: 1865
Re: Iterator on non-existing structure
« Reply #16 on: January 16, 2025, 10:54:14 pm »
Why shouldn't it work? The for in loop calls GetEnumerator, with self being nil. GetEnumerator then calls:
Code: Pascal  [Select][+][-]
  1. Result := TFPGListEnumeratorSpec.Create(Self);
Just passing self (nil) over to the TFPGListEnumerator<T>.Create, which does not touch FList until the first call to the MoveNext. The call to MoveNext then would immediately return false, causing Current to never be queried and thereby never try to access the list.

Also GetEnumerator is not virtual, so it's completely fine to call it with nil

PascalDragon

  • Hero Member
  • *****
  • Posts: 5870
  • Compiler Developer
Re: Iterator on non-existing structure
« Reply #17 on: January 18, 2025, 05:08:52 pm »
Why shouldn't it work? The for in loop calls GetEnumerator, with self being nil. GetEnumerator then calls:

Gotta admit that I hadn't looked at how the TFPGList.GetEnumerator method is implemented. Nevertheless it's bad style anyway, because someone changing that method to access Self will result in it blowing up again. Explicitly checking for Self should only be done in really constrained circumstances, like TObject.Free.

 

TinyPortal © 2005-2018