arrays 'इम्प्लीसिट' क्लास ऑपरेटर के साथ एक गतिशील सरणी युक्त डेल्फी रिकॉर्ड की शुरुआत



delphi dynamic (1)

ऐसा लगता है कि आपको वहां कोडजन के साथ एक बग मिला (और यह Win64 कंपाइलर में भी मौजूद है)। मैंने जेनरेट एएसएम को देखा और ऐसा लगता है कि कंपाइलर ऑपरेटर अधिभार के लिए गलत निर्देश उत्पन्न करता है। यही कारण है कि ऑपरेटर अधिभार के अंदर सरणी में गलत मान समाप्त होते हैं। कृपया गुणवत्ता पोर्टल में इसकी रिपोर्ट करें।

खराब परिणाम के लिए उत्पन्न कोड:

Project109.dpr.46: r3 := iArray;
0040B1F2 A1FC044100       mov eax,[$004104fc]
0040B1F7 8945E8           mov [ebp-$18],eax
0040B1FA 837DE800         cmp dword ptr [ebp-$18],$00
0040B1FE 740B             jz $0040b20b
0040B200 8B45E8           mov eax,[ebp-$18]
0040B203 83E804           sub eax,$04
0040B206 8B00             mov eax,[eax]
0040B208 8945E8           mov [ebp-$18],eax
0040B20B 8D4DD8           lea ecx,[ebp-$28]
0040B20E 8B55E8           mov edx,[ebp-$18]
0040B211 4A               dec edx
0040B212 B8FC044100       mov eax,$004104fc // <-- wrong one
0040B217 E87CF5FFFF       call TRec.&op_Implicit

एक समान विधि के लिए कोड:

Project109.dpr.47: r3 := TRec.Implicit(iArray);
0040B22F A1FC044100       mov eax,[$004104fc]
0040B234 8945E4           mov [ebp-$1c],eax
0040B237 837DE400         cmp dword ptr [ebp-$1c],$00
0040B23B 740B             jz $0040b248
0040B23D 8B45E4           mov eax,[ebp-$1c]
0040B240 83E804           sub eax,$04
0040B243 8B00             mov eax,[eax]
0040B245 8945E4           mov [ebp-$1c],eax
0040B248 8D4DD4           lea ecx,[ebp-$2c]
0040B24B 8B55E4           mov edx,[ebp-$1c]
0040B24E 4A               dec edx
0040B24F A1FC044100       mov eax,[$004104fc] // <-- correct one
0040B254 E8CFF5FFFF       call TRec.Implicit

हालांकि आप पैरामीटर प्रकार TArray<UInt64> साथ लागू ऑपरेटर के लिए एक और अधिभार जोड़कर इससे बच सकते हैं और फिर अपने स्थानीय चर को उस प्रकार के रूप में भी घोषित कर सकते हैं ताकि संकलक सही अधिभार को खो देता है (जिसने इसे गलत कोड नहीं बनाया है मामला)।

लेकिन ध्यान रखें कि यह तभी काम करेगा जब आप TArray<UInt64> चर को पास करते हैं और जब आप डेल्फी सख्त प्रकार के नियमों के कारण array of UInt64 कोई अन्य गतिशील array of UInt64 हैं तो गलत कॉल करें।

अद्यतन : RSP-16084 में यह दोष रिपोर्ट किया गया था और डेल्फी 10.2 टोक्यो में तय किया गया था।

मैं यह पता लगाने की कोशिश कर रहा हूं कि डेल्फी में "अंतर्निहित" वर्ग ऑपरेटर (बर्लिन 10.1 अपडेट 1) का उपयोग करके गतिशील सरणी वाले रिकॉर्ड को प्रारंभ करना संभव है या नहीं।

संलग्न कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है:

ci iA r1 r2 r3
1  1  1  1  49694764491115752
2  2  2  2  11570520
3  3  3  3  0
4  4  4  4  0
5  5  5  5  0
  • TREC एक रिकॉर्ड प्रकार है जिसमें एक गतिशील सरणी है जिसे मैं प्रारंभ करना चाहता हूं।
  • सीआई पूर्णांक की निरंतर सरणी है।
  • ia पूर्णांक की एक गतिशील सरणी है।
  • आर 1, आर 2, आर 3 टाइप ट्रेक के रिकॉर्ड हैं जो विभिन्न तरीकों से शुरू किए जाते हैं।

जैसा कि आप आउटपुट से देख सकते हैं, पहले दो असाइनमेंट (आर 1, आर 2), स्थिरांक का उपयोग करते हुए काम करते हैं। तीसरा असाइनमेंट r3 := iArray संकलक द्वारा स्वीकार किया जाता है, लेकिन परिणाम टूटा हुआ है। डीबगर से पता चलता है कि TRec.Implicit में v का मान पहले से ही गलत है।

क्या गलत हो रहा है? क्या यह वास्तव में संभव है?

program Project5;

{$APPTYPE CONSOLE}

{$R *.res}

type
  TRec = record
    iArray: array of UInt64;
    class operator Implicit(const v: array of UInt64): TRec;
  end;

{ TRec }

class operator TRec.Implicit(const v: array of UInt64): TRec;
var
  i: integer;
begin
  setlength(Result.iArray, Length(v));
  for i := 0 to High(v) do
    Result.iArray[i] := v[i];
end;

const
  ciArray: array [0 .. 4] of UInt64 = (1, 2, 3, 4, 5);

var
  i         : integer;
  iArray    : array of UInt64;
  r1, r2, r3: TRec;

begin
  iArray := [1, 2, 3, 4, 5];

  r1 := [1, 2, 3, 4, 5];
  r2 := ciArray;
  r3 := iArray;

  Writeln('ci iA r1 r1 r3');
  for I := 0 to High(ciArray) do
    Writeln(ciArray[i], '  ', iArray[i], '  ', r1.iArray[i], '  ', r2.iArray[i], '  ', r3.iArray[i]);

  readln;

end.




record