Arrays 初始化包含带有';隐式';类运算符
我试图弄清楚是否可以使用Delphi(Berlin 10.1 upd 1)中的“隐式”类运算符初始化包含动态数组的记录 附加的程序产生以下输出:Arrays 初始化包含带有';隐式';类运算符,arrays,delphi,dynamic,initialization,record,Arrays,Delphi,Dynamic,Initialization,Record,我试图弄清楚是否可以使用Delphi(Berlin 10.1 upd 1)中的“隐式”类运算符初始化包含动态数组的记录 附加的程序产生以下输出: ci iA r1 r2 r3 1 1 1 1 49694764491115752 2 2 2 2 11570520 3 3 3 3 0 4 4 4 4 0 5 5 5 5 0 TRec是包含要初始化的动态数组的记录类型 ci是整数的常量数组 ia是一个动态整数数组 r1、r2、r3是以不同方式初始化的TRec
ci iA r1 r2 r3
1 1 1 1 49694764491115752
2 2 2 2 11570520
3 3 3 3 0
4 4 4 4 0
5 5 5 5 0
- TRec是包含要初始化的动态数组的记录类型
- ci是整数的常量数组
- ia是一个动态整数数组
- r1、r2、r3是以不同方式初始化的TRec类型记录
r3:=iArray
,但结果被破坏。调试器显示TRec.Implicit
中的v
值已经错误
这里出了什么问题?这可能吗
program Project5;
{$APPTYPE CONSOLE}
{$R *.res}
type
TRec = record
iArray: array of UInt64;
class operator Implicit(const v: array of UInt64): TRec;
end;
{ TRec }
class operator TRec.Implicit(const v: array of UInt64): TRec;
var
i: integer;
begin
setlength(Result.iArray, Length(v));
for i := 0 to High(v) do
Result.iArray[i] := v[i];
end;
const
ciArray: array [0 .. 4] of UInt64 = (1, 2, 3, 4, 5);
var
i : integer;
iArray : array of UInt64;
r1, r2, r3: TRec;
begin
iArray := [1, 2, 3, 4, 5];
r1 := [1, 2, 3, 4, 5];
r2 := ciArray;
r3 := iArray;
Writeln('ci iA r1 r1 r3');
for I := 0 to High(ciArray) do
Writeln(ciArray[i], ' ', iArray[i], ' ', r1.iArray[i], ' ', r2.iArray[i], ' ', r3.iArray[i]);
readln;
end.
看起来您在那里发现了一个带有codegen的bug(它也存在于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.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移动eax,[ebp-$18]
0040B203 83E804子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十二月edx
0040B212 B8FC044100 mov eax,$004104fc//确保这是可能的。我也是为我的biginger
type()做的。但请确保执行某种写时复制(COW),因此每次修改数组时,必须确保它是唯一的副本。@Rudyvelthui编译器错误使其无法执行,不是吗。除非你解决了这个bug或者从供应商那里得到了修复。好吧,看来Implicit()
的dynarray参数是一个特例。否则它会起作用。记录可以包含一个dynarray,好吧,dyn数组参数是手头的主题,所以让我们关注问题的主题是“带有dynarray和隐式运算符的记录”,而不是“带有开放数组参数的隐式运算符的记录”。不一样。这似乎在Delphi10.2 Tokyo中得到了修复。
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