, 당신은 다음과 같은 크기를 확인할 수 있습니다F # generic 구조체에 여분의 __dummy 필드가있는 이유는 무엇입니까? F # 대화를 사용
는// 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
필드의 존재가 될 것으로 보인다. 다시 F # 대화를 사용하면이 typeof
를 사용하여 볼 수 있습니다
typeof<A>
는DeclaredFields = [|Int32 i|]
typeof<B<int>>
이__dummy
필드가 추가되었습니다 왜 이해가 안DeclaredFields = [|Int32 i; Int32 __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
I을 :
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이 보여 가정 해보자.은 구조체에 인스턴스 필드가 없음을 의미합니다. 그러나 작성된 코드는 구조체 이에 있는지 여부를 테스트하는 것입니다. 인스턴스 필드는 광산을 포함한 대부분의 구조체에서 true가됩니다. 최종 테스트의 마지막 부분은 일반적인 유형 매개 변수가 있는지 여부입니다. 따라서 requiresExtraField
은 type A
(일반이 아님)의 경우 false
이고 type B
(일반 유형의 경우)은 true
입니다.
이것은 컴파일러의 버그입니까? 아니면 코드가 맞습니까? 그것이 올 바르면이 __dummy
필드의 목적은 무엇입니까? 내가 그것을 피할 수있는 방법이 있습니까?
// sizeof<AA> = 1
type AA = struct end
// sizeof<BB<int>> = 1
type BB<'T> = struct end
내가 가지고 싶은 이유 : 다른 테스트로
, 나는 내가 __dummy
필드가 더 이상 추가되었음을 보여주는, 다음과 같은 크기를 가지고, 놀랍게도 내 유일한 인스턴스 필드, 그리고 제거 참조 유형이 아닌 값 유형은 데이터 구조에 이러한 객체를 많이 전달하는 것이 아니라 많은 객체를 저장한다는 것입니다.
"cenv.opts.workAroundReflectionEmitBugs"는 일부 반향 방출 버그의 해결 방법임을 제안합니다. C#이 똑같은 일을하는지 확인 했습니까? - 코드 기록을 간략하게 살펴보면 적어도 2010 년 11 월의 F # 2로 거슬러 올라갑니다.0 - 온라인 AFAIK에서 사용할 수있는 코드의 가장 오래된 버전입니다. – Asik
sizeof > = 4 프로그램에서 대화식 크기가 실제로 문제입니까? – jyoung
@jyoung : 오, 나는 이것이 F # Interactive의 경우에 불과하다는 것을 알지 못했습니다. 난 그냥 sizeof > 프로그램에서, 당신이 말한 것처럼, 그것을 시도하고 4, 반면에 F 인터랙티브 8 제공합니다. 그럼 내 문제는 해결, 감사합니다! Google을 사용하여 소스 파일을 찾았으므로 더 큰 그림이 무엇인지 알지 못했습니다. 해당 fsi 파일에서 끝에있는 공용'IlxAssemblyGenerator' 유형은 단일 어셈블리에 대한 증분 ILX 코드 생성기임을 나타냅니다. 내 교화를 위해서, 그게 다 뭐야? – bananasareyellow