On 17.07.2017 19:20, Ryan Joseph wrote: > >> On Jul 17, 2017, at 10:58 AM, Sven Barth via fpc-pascal >> <fpc-pascal@lists.freepascal.org> wrote: >> >> I'll need to check whether Delphi allows that for helpers (doesn't matter >> whether the extended type is a specialization or not). >> >> > > Thanks Sven. Records/objects/classes in Pascal feel very confused right now. > Records are moving in the direction of legacy style “objects” which are > allocated on the stack so I wonder why objects just don’t replace records > already? Having said that why don’t classes just replace records/objects > except they allocate on the stack? These 3 distinct constructs don’t really > make sense more imo.
First of records can't replace objects, because objects have inheritance and a VMT for virtual methods not to mention destructors. Secondly this would lead to all kind of backwards compatibility problems. Classes are not designed to be allocated on the stack. They are only on the heap, thus they are a different kind of beast to records and objects. And records - unlike objects and classes - can have operator overloads *inside* of them which allows this operators to be used inside generic specializations. I have also another solution for your original problem. Take this code: === code begin === program trechelpfld; {$mode objfpc} {$modeswitch advancedrecords} type TTest = record x, y: Double; end; TTestHelper = record helper for TTest private function GetWidth: Double; inline; function GetHeight: Double; inline; procedure SetWidth(aValue: Double); inline; procedure SetHeight(aValue: Double); inline; public property Width: Double read GetWidth write SetWidth; property Height: Double read GetHeight write SetHeight; end; function TTestHelper.GetWidth: Double; begin Result := x; end; function TTestHelper.GetHeight: Double; begin Result := y; end; procedure TTestHelper.SetWidth(aValue: Double); begin x := aValue; end; procedure TTestHelper.SetHeight(aValue: Double); begin y := aValue; end; var t: TTest; x, y: Double; begin t.x := 42.0; t.y := 21.0; x := t.Width; y := t.Height; t.Width := y; t.Height := x; end. === code end === Through the use of "inline" this results in code without calls as the assembly output of the main procedure without any optimizations shows: === code begin === .section .text.n_main .balign 16,0x90 .globl PASCALMAIN .type PASCALMAIN,@function PASCALMAIN: .globl main .type main,@function main: .Lc21: # Temps allocated between rbp-16 and rbp+0 # [45] begin pushq %rbp .Lc23: .Lc24: movq %rsp,%rbp .Lc25: leaq -16(%rsp),%rsp call FPC_INITIALIZEUNITS # [46] t.x := 42.0; movq _$TRECHELPFLD$_Ld1,%rax movq %rax,U_$P$TRECHELPFLD_$$_T # [47] t.y := 21.0; movq _$TRECHELPFLD$_Ld2,%rax movq %rax,U_$P$TRECHELPFLD_$$_T+8 # [49] x := t.Width; movsd U_$P$TRECHELPFLD_$$_T,%xmm0 movsd %xmm0,U_$P$TRECHELPFLD_$$_X # [50] y := t.Height; movsd U_$P$TRECHELPFLD_$$_T+8,%xmm0 movsd %xmm0,U_$P$TRECHELPFLD_$$_Y # [52] t.Width := y; movq U_$P$TRECHELPFLD_$$_Y,%rax movq %rax,U_$P$TRECHELPFLD_$$_T # [53] t.Height := x; movq U_$P$TRECHELPFLD_$$_X,%rax movq %rax,U_$P$TRECHELPFLD_$$_T+8 # [54] end. call FPC_DO_EXIT leave ret .Lc22: .Le4: .size main, .Le4 - main === code end === It might be more to write, but it works... Regards, Sven _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal