The default comparer for such a type is pretty arbitrary. The compiler doesn't use any knowledge of the make up of the record. You've certainly not told it which member you want to be the primary sort key. So it is free to do what it wants.
In 32 bit the default comparer for an 8 byte record is implemented with a call to a CompareMem
-like function. So bytes are compared in increasing order of address. Thus the key is more significant.
Under 64 bit the default comparer treats the type as an unsigned 64 bit integer and so bytes are compared in decreasing address order, this being little endian. And so the value is more significant.
The pertinent code is in the implementation section of Generics.Defaults
:
function Comparer_Selector_Binary(info: PTypeInfo; size: Integer): Pointer;
begin
case size of
// NOTE: Little-endianness may cause counterintuitive results,
// but the results will at least be consistent.
1: Result := @Comparer_Instance_U1;
2: Result := @Comparer_Instance_U2;
4: Result := @Comparer_Instance_U4;
{$IFDEF CPUX64}
// 64-bit will pass const args in registers
8: Result := @Comparer_Instance_U8;
{$ENDIF}
else
Result := MakeInstance(@Comparer_Vtable_Binary, size);
end;
end;
The bottom line is that you need to supply a real comparer whenever you wish to sort records. Only built in numeric and string types have well defined ordered comparers.