Sample code:
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.
This code give this debug output:
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)
It seems that the compiler for different variables create different code:
- LSomeRec them pass as var parameter(as expected).
- For GSomeRec and FSomeRec compiler create temporary variabale, passing her and after assign value for normal variable.
Is this normal? If is normal can you give me link to specification(documentation), please.
PS
A small addition...
Here it is written:
For static-array, record, and set results, if the value occupies one byte it is returned in AL; if the value occupies two bytes it is returned in AX; and if the value occupies four bytes it is returned in EAX. Otherwise, the result is returned in an additional var parameter that is passed to the function after the declared parameters
But in fact, this rule is not satisfied. If it holds debugger output would be as follows:
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)