एफ # इंटरएक्टिव उपयोग करके, आप निम्न आकारों की पुष्टि कर सकते हैं:एफ # जेनेरिक स्ट्रक्चर में अतिरिक्त __dummy फ़ील्ड क्यों है?
// sizeof<A> = 4 bytes
type A (i: int) = struct end
// sizeof<B<int>> = 8 bytes (use any type parameter)
type B<'T> (i: int) = struct end
अतिरिक्त आकार के लिए कारण सामान्य मामले में एक पूर्णांक __dummy
क्षेत्र की उपस्थिति हो रहा है। फिर से एफ # इंटरएक्टिव का उपयोग करना, आप इस का उपयोग कर typeof
देख सकते हैं:
typeof<A>
से पता चलताDeclaredFields = [|Int32 i|]
typeof<B<int>>
DeclaredFields = [|Int32 i; Int32 __dummy|]
से पता चलता मुझे समझ नहीं आता क्यों इस __dummy
क्षेत्र जोड़ा गया है।
मुझे लगता है कि कोड में जोड़ने के लिए जिम्मेदार यहाँ है:
let requiresExtraField =
let isEmptyStruct =
(match ilTypeDefKind with ILTypeDefKind.ValueType -> true | _ -> false) &&
// All structs are sequential by default
// Structs with no instance fields get size 1, pack 0
tycon.AllFieldsAsList |> List.exists (fun f -> not f.IsStatic)
isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty
मैं:
if requiresExtraField then
yield mkILInstanceField("__dummy",cenv.g.ilg.typ_int32,None,ILMemberAccess.Assembly) ]
Line 6290 जहां requiresExtraField
परिभाषित किया जाता है:
https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/ilxgen.fs
Line 6377 यह दिखाता है मान लें कि isEmptyStruct
का मतलब यह है कि संरचना में कोई उदाहरण फ़ील्ड नहीं है। लेकिन लिखित कोड यह जांच रहा है कि संरचना में कोई उदाहरण फ़ील्ड है, जो कि मेरे समेत अधिकांश structs के लिए सच है। मुझे लगता है कि अंतिम परीक्षण का अंतिम भाग यह है कि क्या कोई सामान्य प्रकार पैरामीटर हैं। तो requiresExtraField
type A
(जेनेरिक नहीं) और true
type B
(सामान्य प्रकार) के लिए false
है।
क्या यह एक कंपाइलर बग है, या कोड सही है? यदि यह सही है, तो __dummy
फ़ील्ड का उद्देश्य क्या है? क्या कोई रास्ता है जिससे मैं इसे टालने से बच सकता हूं?
एक और परीक्षण के रूप में, मैं आश्चर्यजनक रूप से मेरी एक और केवल उदाहरण क्षेत्र, और नहीं हटाया, मैं निम्न आकारों मिला है, दिखा रहा है कि __dummy
क्षेत्र नहीं रह गया है जोड़ा गया है:
// sizeof<AA> = 1
type AA = struct end
// sizeof<BB<int>> = 1
type BB<'T> = struct end
कारण मैं करना चाहते हैं एक संदर्भ प्रकार के बजाए एक मूल्य प्रकार यह है कि मैं अपने डेटा संरचनाओं में इन वस्तुओं में से कई को संग्रहीत करूँगा, न केवल उन्हें पास कर रहा हूं।
"cenv.opts.workAroundReflectionEmitBugs" बताता है कि यह कुछ प्रतिबिंब उत्सर्जित बग के लिए एक कामकाज है। क्या आपने जांच की है कि सी # वही काम करता है? - कोड इतिहास पर एक त्वरित रूप से पता चलता है कि यह कम से कम नवंबर 2010, एफ # 2 पर वापस आता है।0 - ऑनलाइन AFAIK उपलब्ध कोड का सबसे पुराना संस्करण। – Asik
एक प्रोग्राम में > = 4 के आकार के बाद, इंटरैक्टिव में इसका आकार वास्तव में आपके लिए एक मुद्दा है? – jyoung
@jyoung: ओह, मुझे कभी एहसास नहीं हुआ कि यह केवल एफ # इंटरएक्टिव के मामले में था। मैंने अभी तक एक कार्यक्रम में > आकार का प्रयास किया है, जैसा कि आपने कहा था, और यह 4 देता है, जबकि एफ # इंटरएक्टिव 8 देता है। फिर मेरा मुद्दा हल हो गया है, धन्यवाद! मैंने Google का उपयोग करके उस स्रोत फ़ाइल को पाया, इसलिए मुझे इसके बारे में बड़ी तस्वीर नहीं पता था। इसी एफएसआई फ़ाइल में, अंत में सार्वजनिक 'IlxAssemblyGenerator' प्रकार का कहना है कि यह एक एकल असेंबली_ के लिए एक वृद्धिशील आईएलएक्स कोड जेनरेटर है। बस मेरे संपादन के लिए, यह सब क्या है? – bananasareyellow