Delphi 10.3 Rio - 是否需要初始化内联声明的记录变量?

标签 delphi delphi-10.3-rio

我对 Delphi 10.3 Rio 内联变量声明感到非常兴奋。但是我遇到了奇怪的问题,似乎我需要在内联声明后初始化记录:

program Project8;
{$APPTYPE CONSOLE}
{$R *.res}

uses System.SysUtils,classes;

procedure DoEvil;
  //var sr:TSearchRec; //A
begin
  //var sr:= default(TSearchRec); //B
  var sr:TSearchRec; //C
  sr.Name := EmptyStr; //D
  FindFirst('*.*',faAnyFile,sr);
  while sr.Name<>EmptyStr do
  begin
    Writeln(sr.name);
    sr.Name := EmptyStr;
    FindNext(sr);
  end;
end;

begin
  try
     DoEvil;
    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

如果我在线声明 sr,代码可以正常工作:

  • //A(旧式声明)或在线
  • //B(带初始化的内联声明)。

但是如果我在线声明 sr

  • //C 然后它在//D 行崩溃,分别在 system.pas 的第 26222 行:

    MOV     ECX,[EDX-skew].StrRec.refCnt    { fetch refCnt                 }
    

异常(exception):

Exception class $C0000005 with message 'access violation at 0x0040ac98: read of address 0xfffffff9'. Process Project8.exe (18928)

我假设从地址 -6 开始,字符串成员 sr.name 未初始化并且为 nil。

为了完整起见,Delphi 是新的 10.3 版本 1: Embarcadero® Delphi 10.3 版本 26.0.33219.4899 - 已安装更新 1

最佳答案

我查看了 CPU 窗口,发现了一些奇怪的地方。

如果我使用旧式 var-block(您的版本 //A),CPU 窗口将显示对 System._InitializeRecord 的调用,正如它应该的那样。一切都很好,很正常。

如果我将内联声明与 Default() (您的版本 //B)一起使用,则本地记录将被清空,然后使用 System. _FinalizeRecord,然后再次清空。这很奇怪而且没用,但它确实有效。

但是,如果我使用您的版本 //C,则不会执行任何操作来初始化记录:不会清空,也不会_InitializeRecord。当我测试你的代码时,事情确实有效,但我可能只是幸运。

所以这显然是一个错误。请举报Embarcadero Quality Portal .

<小时/>

猜测这是在测试默认构造函数、默认析构函数和重载赋值运算符时对编译器所做的其余更改(但随后被删除并推迟到下一个版本)。其中一些更改相当脑残(例如版本 B 中的清零、最终确定和再次清零),我猜其中一些更改已被遗忘。

更新

显然这已经报告给 QP:

关于Delphi 10.3 Rio - 是否需要初始化内联声明的记录变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54987996/

相关文章:

delphi - (TSQLConnection) 为什么 Left 和 Top 属性仅在 .dfm 文件中可用?

Delphi 2010 搜索环绕

delphi - 如何检测弹出菜单的子菜单的弹出(以及如何动态填充它)?

sockets - Indy TCP Socket 可以在两个线程之间共享吗?

multithreading - 在主线程中调用 TThread.Synchronize

Delphi 10.3 Rio - 删除欢迎页面

delphi - 从 32 位或 64 位程序创建快捷方式时,快捷方式文件的文件哈希不同

xml - Delphi XML (MSXML) 例程的二次运行时

delphi - 创建具有命名子组件的组件?