Я очень взволнован объявлениями встроенных переменных 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 }
за исключением:
Класс исключения $ C0000005 с сообщением «Нарушение прав доступа по адресу 0x0040ac98: чтение адреса 0xfffffff9». Процесс Project8.exe (18928)
Из адреса -6 я бы предположил, что строковый член sr.name не инициализирован и равен нулю.
Напоминаем, что Delphi представляет собой новую версию 10.3 Release 1: Embarcadero® Delphi 10.3 Version 26.0.33219.4899 - Установленное обновление 1
FindFirst
возвращает 0. В этом случае вам нужно будет вызватьFindClose
после цикла. - person LU RD   schedule 04.03.2019System._InitializeRecord
. Если я использую вашу// C
строку, это не так. Так что, вероятно, в моем случае это ноль, а в вашем случае это не так. Если я введу код в окне ЦП, я получу вашу ошибку. Похоже, это все-таки ошибка, и мне просто повезло - person Rudy Velthuis   schedule 04.03.2019while
, fwiw. - person MartynA   schedule 04.03.2019