for Enum in Arr do
Writeln(ord(Enum));
Here, Arr
is an array, and so the items of the array are output in order. The documentation says:
The array is traversed in increasing order.
Hence 2
is output before 0
.
for Enum in [enum3, enum1] do
Writeln(ord(Enum));
Here, [enum3, enum1]
is a set and the enumerator for a set happens to enumerate in order of increasing ordinal value. So the output has 0
first.
I don't think that is stated anywhere in the documentation that sets are enumerated in that order, but empirically that appears to be the case. However, since sets are an unordered type one should not be relying on their enumeration order anyway.
So the question then becomes understanding how [...]
can be a set or an array at different points in the code. This all stems from the new XE7 dynamic array syntax which introduces (another) syntactical ambiguity. When we write
Arr := [enum3, enum1];
then [enum3, enum1]
is an array. The compiler knows that Arr
is an array and that information defines the type of the literal.
But when we write
for Enum in [enum3, enum1] do
then [enum3, enum1]
is a set. Here the literal could in principle be either array or set. In such situations, I believe that the compiler will always prefer sets.
Again, I can't find any documentation that states that this is so, but empirically this is the case. Presumably since set enumerators pre-date the new dynamic array syntax they take precedence when there is ambiguity.
The meaning of a literal of the form [...]
depends on its context.
[]
was always a set. Only after the new synatx was introduced, dynarrays could be initialized with[]
syntax. So indeed, Arr is an array (what else?), while the general literal[...]
has always denoted a set, since the good old Pascal days.So there is nothing weird about it, IMO. Enumerators do not necessarily have a special order, but IIRC it was mentioned somewhere that sets are enumerated in increasing ordinal order. – Inigo