यह एक दोष XE8 में शुरू की गई है। यहां सबसे सरल प्रजनन है जो मैं उत्पन्न कर सकता हूं।
{$APPTYPE CONSOLE}
uses
System.Generics.Collections;
var
Queue: TQueue<TArray<Byte>>;
begin
Queue := TQueue<TArray<Byte>>.Create;
Queue.Enqueue(nil);
Writeln(Queue.Count);
end.
आउटपुट XE7 और सिएटल में XE7 और 0 में 1 है।
यह पहले ही एम्बरकैडेरो को सूचित किया गया है: RSP-13196।
Enqueue
के कार्यान्वयन इस तरह दिखता है:
procedure TQueue<T>.Enqueue(const Value: T);
begin
if IsManagedType(T) then
if (SizeOf(T) = SizeOf(Pointer)) and (GetTypeKind(T) <> tkRecord) then
FQueueHelper.InternalEnqueueMRef(Value, GetTypeKind(T))
else
FQueueHelper.InternalEnqueueManaged(Value)
else
case SizeOf(T) of
1: FQueueHelper.InternalEnqueue1(Value);
2: FQueueHelper.InternalEnqueue2(Value);
4: FQueueHelper.InternalEnqueue4(Value);
8: FQueueHelper.InternalEnqueue8(Value);
else
FQueueHelper.InternalEnqueueN(Value);
end;
end;
जब T
एक गतिशील सरणी है, FQueueHelper.InternalEnqueueMRef
शाखा चुना जाता है। यह बदले में इस तरह दिखता है: TTypeKind.tkDynArray
के लिए कोई प्रविष्टि नहीं है
procedure TQueueHelper.InternalEnqueueMRef(const Value; Kind: TTypeKind);
begin
case Kind of
TTypeKind.tkUString: InternalEnqueueString(Value);
TTypeKind.tkInterface: InternalEnqueueInterface(Value);
{$IF not Defined(NEXTGEN)}
TTypeKind.tkLString: InternalEnqueueAnsiString(Value);
TTypeKind.tkWString: InternalEnqueueWideString(Value);
{$ENDIF}
{$IF Defined(AUTOREFCOUNT)}
TTypeKind.tkClass: InternalEnqueueObject(Value);
{$ENDIF}
end;
end;
ध्यान दें कि वहाँ। चूंकि इन दो विधियों को रेखांकित किया गया है, इनलाइनर इसे सब कुछ कम करने के लिए संकुचित करता है। जब आप Enqueue
गतिशील सरणी करते हैं तो कोई कार्रवाई नहीं की जाती है।
कोड इस तरह देखा XE7 के अच्छे पुराने दिनों में वापस
procedure TQueue<T>.Enqueue(const Value: T);
begin
if Count = Length(FItems) then
Grow;
FItems[FHead] := Value;
FHead := (FHead + 1) mod Length(FItems);
Inc(FCount);
Notify(Value, cnAdded);
end;
वहाँ प्रकार विशिष्ट दोष के लिए कोई गुंजाइश।
मुझे नहीं लगता कि आपके लिए एक आसान कामकाज है। शायद आगे बढ़ने का सबसे सुविधाजनक तरीका XE7 TQueue
के लिए कोड लेना और XE8 और सिएटल से टूटे हुए कार्यान्वयन के स्थान पर इसका उपयोग करना है। रिकॉर्ड के लिए, मैंने एम्बरकाडेरो जेनेरिक संग्रहों को छोड़ दिया है और अपनी कक्षाओं का उपयोग किया है।
पिछली कहानी यह है कि XE8 में, एम्बरकैडेरो ने जेनेरिक के कार्यान्वयन में कमी को संबोधित करने का निर्णय लिया। जब भी आप एक सामान्य प्रकार को तत्काल बनाते हैं, तो सभी विधियों की प्रतियां बनाई जाती हैं। कुछ तरीकों के लिए, अलग-अलग तत्कालताओं के लिए समान कोड उत्पन्न होता है।
तो यह समान कोड रखने के लिए TGeneric<TFoo>.DoSomething
और TGeneric<TBar>.DoSomething
के लिए काफी आम है। अन्य भाषाओं के लिए अन्य कंपाइलर, सी ++ टेम्पलेट्स, नेट जेनिक्स इत्यादि, इस डुप्लिकेशन को पहचानते हैं और समान जेनेरिक तरीकों को एक साथ मिलाते हैं। डेल्फी कंपाइलर नहीं करता है। अंतिम परिणाम सख्ती से जरूरी से एक बड़ा निष्पादन योग्य है।
XE8 Embarcadero में इस बात से निपटने का फैसला किया कि मैं पूरी तरह से गलत तरीका था। इस मुद्दे के मूल कारण पर हमला करने के बजाय, कंपाइलर, उन्होंने अपने सामान्य संग्रह वर्गों के कार्यान्वयन को बदलने का फैसला किया। यदि आप Generics.Collections
में कोड देखते हैं, तो आप देखेंगे कि यह XE8 में पूरी तरह से फिर से लिखा गया है। जहां पहले XE7 और इससे पहले का कोड पठनीय था, XE8 से अब यह बहुत जटिल और अपारदर्शी है।इस निर्णय के निम्नलिखित परिणाम थे:
- जटिल कोड में कई त्रुटियां थीं। XE8 जारी होने के तुरंत बाद इनमें से कई पाए गए और तय किए गए हैं। आप एक और दोष पर ठोकर खाई है। एक चीज जिसे हमने सीखा है वह है कि एम्बरकाडेरो का आंतरिक परीक्षण सूट पर्याप्त रूप से अपने संग्रह वर्गों का प्रयोग नहीं करता है। यह स्पष्ट रूप से स्पष्ट है कि उनके परीक्षण अपर्याप्त हैं।
- कंपाइलर की बजाय अपनी लाइब्रेरी को बदलकर, उन्होंने आरटीएल कक्षाएं बनाई हैं। जेनेरिक कोड ब्लोट के साथ मूल मुद्दा तीसरे पक्ष के वर्गों के लिए बना हुआ है। अगर एम्बरकाडेरो ने स्रोत पर इस मुद्दे को ठीक किया था तो न केवल वे XE7 से सरल और सही संग्रह कक्षा कोड बनाए रख सकते थे, लेकिन सभी तीसरे जेनेरिक कोड को फायदा होगा।
इसके अलावा, हमें अभी तक एक और असंगत बाइट सरणी प्रकार की आवश्यकता नहीं है। 'टीबीइट्स 'का प्रयोग करें। आमतौर पर 'बाइट' के अलावा तत्व प्रकारों के लिए 'TArray' का उपयोग करें। –
मैं सहमत हूं। मूल सरणी टिडबाइट्स (इंडी) – Hans
काम नहीं करती है? –