示例代码的结果奇怪的行为:有记录的功能
unit Main;
interface
uses
Winapi.Windows, System.SysUtils, Vcl.Forms;
type
TSomeRec = record
SomeData: Integer;
SomePtr: Pointer;
procedure Reset;
class operator Implicit(const SomeData: Integer): TSomeRec;
end;
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
private
FSomeRec: TSomeRec;
end;
var
MainForm: TMainForm;
GSomeRec: TSomeRec;
implementation
{$R *.dfm}
function SomeFunc(Value: Integer): TSomeRec;
begin
OutputDebugString(PWideChar(Result.SomeData.ToString + ' : ' + Integer(Result.SomePtr).ToString));
Result.SomeData := Value;
end;
{ TSomeRec }
procedure TSomeRec.Reset;
begin
SomeData := 5;
SomePtr := nil;
end;
class operator TSomeRec.Implicit(const SomeData: Integer): TSomeRec;
begin
OutputDebugString(PWideChar(Result.SomeData.ToString + ' : ' + Integer(Result.SomePtr).ToString));
Result.SomeData := SomeData;
end;
{ TMainForm }
procedure TMainForm.FormCreate(Sender: TObject);
var
LSomeRec: TSomeRec;
begin
LSomeRec.Reset;
GSomeRec.Reset;
FSomeRec.Reset;
LSomeRec := 1;
GSomeRec := 1;
FSomeRec := 1;
LSomeRec.Reset;
GSomeRec.Reset;
FSomeRec.Reset;
LSomeRec := SomeFunc(1);
GSomeRec := SomeFunc(1);
FSomeRec := SomeFunc(1);
end;
end.
此代码给这个调试输出:
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 172555996 : 1638080 Process DPITest.exe (1764)
Debug Output: 1 : 1638080 Process DPITest.exe (1764)
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 1 : 1638080 Process DPITest.exe (1764)
Debug Output: 1 : 1638080 Process DPITest.exe (1764)
看来,编译器为不同的变量建立不同代码:
- LSomeRec他们通过作为var参数(作为expecte d)。
- 对于GSomeRec和FSomeRec编译器,创建临时变量,在为正常变量赋值后传递她。
这是正常的吗?如果是正常的,请给我链接到规范(文档)。
PS
添加少量...
Here上写着:
对于静态数组,记录,并设置结果,如果值占用一个字节 它在AL中返回;如果该值占用两个字节,则在AX中返回 ;如果该值占用4个字节,则返回EAX中的 。否则,结果被传递给函数的声明参数
但事实上,这条规则是不成立后,一个额外的变量参数 返回。如果它包含调试器输出如下:
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 5 : 0 Process DPITest.exe (1764)
Debug Output: 5 : 0 Process DPITest.exe (1764)
我不认为这是重复的 - 返回值被初始化是答案的一部分,但我认为OP期望隐式类操作符的行为与它的行为不同。具体来说,他们似乎预计'result'会预先加载左侧变量的记录内容(即:操作员将提供零碎分配/替换的目标记录)。这根本不是那么回事。 –
我没有把它写进去,而且我也没有看到作为一个笨蛋关闭它有什么不好。我们积极鼓励这样做。每个人都可以建立这些链接。我看不出有什么比返回值没有被初始化更多的东西。 –
@Vasek您的重置方法需要麻烦。变异值的值类型的方法往往会造成混淆。倾向于使用简单的常量赋值。 –