0

Using Delphi Rio 10.3.3 I created a record with two fields, an equality comparison operator. One of the fields is an enumerator. When I create two variables of this type without 'building them' and compare with another, if the variable 'inline', the comparison returns as equals. However, if the variable is by the traditional way, the comparison returns False. The enumerator field is not initializing when it is declared in traditional way.

  type
    TPropT = (ptYes, ptNo, ptMaybe);
    MyConfuseRecord = record
      var
       Fprop: String;
       FpropT: TPropT;
    constructor Create(_fieldName: string; aPropT: TPropT = ptMaybe);
    class operator Equal(_aLeft, _aRight: MyConfuseRecord): Boolean;
    class operator NotEqual(_aLeft, _aRight: MyConfuseRecord): Boolean;
    end;

...

constructor MyConfuseRecord.Create(_fieldName: string; aPropT: TPropT);
begin
  Fprop := _fieldName;
  FpropT := aPropT;
end;

class operator MyConfuseRecord.Equal(_aLeft, _aRight: MyConfuseRecord): Boolean;
var
  Comparer: IEqualityComparer<string>;
begin
  Comparer := TEqualityComparer<string>.Default;
  Result := (Comparer.Equals(_aLeft.Fprop, _aRight.Fprop)) and (_aLeft.FpropT = _aRight.FpropT);
end;

class operator MyConfuseRecord.NotEqual(_aLeft, _aRight: MyConfuseRecord): Boolean;
begin
  Result := not (_aLeft = _aRight);
end;

... Testing in diferent ways

procedure CompareMyRecords_Inline;
var
  Rs: Boolean;
begin
  var mRec1: MyConfuseRecord;
  var mRec2: MyConfuseRecord;

  Rs := mRec1 = mRec2; //True (mRec1.FPropT is everytime ZERO)
  OutputDebugString(Pchar('Result (Inline) '+ BooltoStr(Rs, True) + ' | value = ' + Integer(mRec1.FPropT).ToString ) );
end;

procedure CompareMyRecords_Normal;
var
  mRec1, mRec2 : MyConfuseRecord;
  Rs: Boolean;
begin
  Rs := mRec1 = mRec2; //False
  OutputDebugString(Pchar('Result1 (normal) '+ BooltoStr(Rs, True) + ' | value1 = ' + Integer(mRec1.FPropT).ToString + ' value 2 = ' + Integer(mRec2.FPropT).ToString ));
end;

Is this an inconsistency in this version of Delphi?

ps: I read this post and I didn't come to a conclusion.

AnselmoMS
  • 467
  • 3
  • 18
  • 4
    No, it is chance. You are not initialising records. When you create an instance of a class it is initialised to zeroes. That is not the case with rcords. – Dsm Sep 30 '20 at 23:19
  • @Dsm, You are right. I'm not initializing the records, but I thought that variables of the same scope should have the same behavior. In this case, I expected the inline variable not to initialize its enum field, since both are local variables. – AnselmoMS Oct 01 '20 at 10:45
  • You are confusing me, and I think yourself. If it is not initialised it will have the value of whatever was in that position before. That is random, or as good as. Your assertion that the that they do not exert the same behavior is flawed. If you don't intialise the variable to be the same you cannot know whether they they behave the same way or not.. – Dsm Oct 01 '20 at 12:29
  • @Dsm, If the value of an uninitialized local variable (enum) was random, the value of `Result2.PropT` should be 'Out Of Bounds' too, right? but, it is always `ptYes` in all cases that this code runs. This is confuse to me. – AnselmoMS Oct 01 '20 at 13:00
  • You simply can't know. And as far as always giving the same answer, it probably will unless you change the code in some way between runs. That is what I meant by random, sort of. It really isn't random at all; it is just that we can't know in advance what occupied that memory last time. But whatever it is is likely to be from the current program and therefore likely to be the same for every run of the program. Just initialise the records and see what happens. .. – Dsm Oct 01 '20 at 13:27
  • @AnselmoMS An unitialized variable mans that when variable was created it was only set po point to certain memory location that was assigned to it. Now if that memory location hasn't been assigned to anything else before (memory manager had retrieved new memory block from OS) then the value of such variable will be ZERO or equivalent. Because most modern OS zero out the memory before assigning it to certain application. But if variable was set to point to a memory block that was used before by your application it will contain some random data in it ... – SilverWarior Oct 01 '20 at 13:46
  • ... This happens because memory memory manager that your application is using doesn't release the unused memory back to OS but keeps it so that it can later reuse it. This reduces the time that application needs to wait for OS to assign some memory block to your application. That is why on Windows Virtual Memory usage of your application is most of the time greater than the actual memory usage as it contains both the actual used memory and memory that has been assigned to your application but still hasn't been released by the memory manager back to the OS. ... – SilverWarior Oct 01 '20 at 13:50
  • ... Any way I'm pretty sure that if you run your `CompareMyRecords` procedure multiple times during one execution of your program you won't encounter same results every time as your memory manager will start reusing same memory block multiple times which would lead to random data being stored there. – SilverWarior Oct 01 '20 at 13:53
  • @SilverWarior, "if you run your CompareMyRecords procedure multiple times during one execution of your program you won't encounter same results every time"... i will test it. thks – AnselmoMS Oct 01 '20 at 13:55
  • @SilverWarior, as i said using Inline variable, i have the same value for `FpropT` (Zero). As expected, in the usual declaration mode it is given a 'random' value. Run my last Edit tests. – AnselmoMS Oct 01 '20 at 14:31
  • I am imagining that this behavior is related to that [post](https://stackoverflow.com/questions/54987996/delphi-10-3-rio-is-initializaiton-of-inline-declared-record-variables-needed) – AnselmoMS Oct 01 '20 at 15:46
  • 1
    It's difficult to understand why there has been so much discussion here. It's just a local variable and their value is not predictable until you assign it. – David Heffernan Oct 01 '20 at 21:01
  • Default(MyConfuseRecord) – Gabriel Jun 20 '23 at 10:12

0 Answers0