Ответ 1
Похоже, вы обнаружили ошибку с кодегеном там (и она также существует в компиляторе Win64). Я просмотрел сгенерированный asm, и, похоже, компилятор производит неверную инструкцию для перегрузки оператора. Вот почему неправильные значения попадают в массив внутри перегрузки оператора. Сообщите об этом на Портале качества.
Сгенерированный код для плохого результата:
Project109.dpr.46: r3 := iArray;
0040B1F2 A1FC044100 mov eax,[$004104fc]
0040B1F7 8945E8 mov [ebp-$18],eax
0040B1FA 837DE800 cmp dword ptr [ebp-$18],$00
0040B1FE 740B jz $0040b20b
0040B200 8B45E8 mov eax,[ebp-$18]
0040B203 83E804 sub eax,$04
0040B206 8B00 mov eax,[eax]
0040B208 8945E8 mov [ebp-$18],eax
0040B20B 8D4DD8 lea ecx,[ebp-$28]
0040B20E 8B55E8 mov edx,[ebp-$18]
0040B211 4A dec edx
0040B212 B8FC044100 mov eax,$004104fc // <-- wrong one
0040B217 E87CF5FFFF call TRec.&op_Implicit
Код для равного метода:
Project109.dpr.47: r3 := TRec.Implicit(iArray);
0040B22F A1FC044100 mov eax,[$004104fc]
0040B234 8945E4 mov [ebp-$1c],eax
0040B237 837DE400 cmp dword ptr [ebp-$1c],$00
0040B23B 740B jz $0040b248
0040B23D 8B45E4 mov eax,[ebp-$1c]
0040B240 83E804 sub eax,$04
0040B243 8B00 mov eax,[eax]
0040B245 8945E4 mov [ebp-$1c],eax
0040B248 8D4DD4 lea ecx,[ebp-$2c]
0040B24B 8B55E4 mov edx,[ebp-$1c]
0040B24E 4A dec edx
0040B24F A1FC044100 mov eax,[$004104fc] // <-- correct one
0040B254 E8CFF5FFFF call TRec.Implicit
Однако вы можете избежать этого, добавив еще одну перегрузку для оператора Implicit с типом параметра TArray<UInt64>
, а затем также объявите свою локальную переменную как этот тип, чтобы компилятор выбрал правильную перегрузку (тот, в котором он не генерирует неправильный код для в этом случае).
Но имейте в виду, что это будет работать только тогда, когда вы передадите переменные типа TArray<UInt64>
и вызовите неправильный, когда у вас есть другой динамический array of UInt64
из-за правил строгих типов Delphis.
Обновление. Этот дефект был указан в RSP-16084 и исправлен в Delphi 10.2 Tokyo.