- or how the for-in statement changed recently.
Before Delphi 10.4, the statement:
for integer in [] do
would operate on a set, but since then it now operates on an array. Which then also means a bit of different behaviour.
I had missed this change completely, and only recently gotten aware of it since we had a build issue - mixing source from different IDE versions. (BTW: Do not do that).
Since it previously worked on a set - the "list" when traversed would be an ordered list of values with an ordinal value no bigger than 255, and no more than 256 elements, that is now changed. I will list a few examples - illustrating the pre-10.4 behaviour compared to 10.4 and later.
Duplicates and ordering
var
i: integer;
begin
for i in [42, 10, 42, 3, 42, 7] do
WriteLn(i.ToString);
end.
returns:
10.4+: 42, 10, 42, 3, 42, 7
pre10.4: 3,7,10,42
Range
var
i: integer;
begin
for i in [42, 365, MaxInt] do
WriteLn(i.ToString);
end.
10.4+: 42, 365, MaxInt
pre10.4: Does not compile - In 10.3 you get an E1012 Constant expression violates subrange bounds (earlier you might also get an E2024)
To solve that you could replace it with something like:
uses
System.Types,
System.SysUtils;
var
i: integer;
begin
for i in TIntegerDynArray.Create(42, 365, MaxInt) do
WriteLn(i.ToString);
end.
I do think the change is a step up, and does syntax-wise work more like one would expect, so a change for the greater good - but do be aware of the change of behaviour. Another benefit of a newer version is the usage of inline variable declaration and type inference, like in this case:
for var i in [42, 10, 42, 3, 42, 7] do
WriteLn(i.ToString);
/Enjoy