Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Language/Overloading    [ Add a report in this area ]  
Report #:  63301   Status: Closed
Temporary variable created unnecessarily!
Project:  Delphi Build #:  11.0.2902.10471
Version:    11.1 Submitted By:   Janez Atmapuri Makovsek
Report Type:  Basic functionality failure Date Reported:  6/14/2008 11:25:28 AM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   261017
Resolution: As Designed (Resolution Comments) Resolved in Build: : 12.0.3105.14660
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
Hi!

When Implicit or explicit operators are declared on a record and that record is passed to a function which requires either implicit or explicit function, the compiler will create a temporary of the record itself even though the expression is actually a function call.

This is comparable to create a temporary of a variable on which a method is called:

test1(a.test1);

In this case there is no need to create a temporary of the variable a (!!).

This is in case of implicit and explicit type conversion at the same time speed optimization and bug fix. (see the steps)

This report could also be a bug report agains the fact that
operator overloads seem to ignore the
"const" on the input paramter and make a copy of the input variable on the stack despite that.

Thanks!
Atmapuri
Steps to Reproduce:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm3 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


type TMyObject = class
        i: integer;
     end;

    TMyRecord = record
        ab: TMyObject;
        class operator Implicit(const Src: TMyRecord): TMyObject;
        procedure Test;
        end;

var a: TMyRecord;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure Test2(Src: TMyObject);
begin
     Src.i := Src.i + 10;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
    a.ab := nil;
    Test2(a);
    if not Assigned(a.ab) then raise Exception.Create('Not initialized!');
end;

{ TMyRecord }

procedure TMyRecord.Test;
begin
   if not Assigned(ab) then ab := TMyObject.Create;
end;


class operator TMyRecord.Implicit(const Src: TMyRecord): TMyObject;
begin
    Src.test;
    Result := Src.ab;
end;
Workarounds
None
Attachment
None
Comments

Pierre le Riche at 6/16/2008 11:48:52 AM -
This is because records of 4 bytes or less are actually passed by value and not reference. If you increase the size of TMyRecord the problem goes away.

Pierre

Server Response from: ETNACODE01