Generics 为什么F#泛型结构有额外的#伪字段?

Generics 为什么F#泛型结构有额外的#伪字段?,generics,compiler-construction,struct,f#,sizeof,Generics,Compiler Construction,Struct,F#,Sizeof,使用F#Interactive,您可以验证以下尺寸: // 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 其中定义了requireXtraField: let requiresExtraField = let is

使用F#Interactive,您可以验证以下尺寸:

// 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
其中定义了
requireXtraField

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
我假设
isEmptyStruct
意味着该结构没有任何实例字段。但是编写的代码正在测试结构是否有任何实例字段,这对于大多数结构(包括我的结构)都是正确的。我认为最终测试的最后一部分是是否有任何泛型类型参数。因此
requireExtraField
对于
类型A
(非泛型)是
false
,对于
类型B
(泛型)是
true

这是一个编译器错误,还是代码正确?如果它是正确的,那么此
\uu伪
字段的用途是什么?有没有什么办法可以避免我的病

作为另一个测试,我删除了我唯一的实例字段,毫不奇怪,我得到了以下大小,表明不再添加
\u dummy
字段:

// sizeof<AA> = 1
type AA = struct end

// sizeof<BB<int>> = 1
type BB<'T> = struct end
//sizeof=1
类型AA=结构端
//sizeof=1

键入BB解释由@jyoung在我原始帖子下方的评论中给出


requireExtraField
的最后一行还测试
cenv.opts.workaroundReflectionMittBugs
。此标志似乎已在中设置。代码行是:

workAroundReflectionEmitBugs=tcConfig.isInteractive; // REVIEW: is this still required?

因此,额外的
\uu dummy
字段的问题只出现在F#Interactive中。

“cenv.opts.workaroundReflectionMitbugs”表明这是一些反射发射bug的解决方法。你检查过C#是否做了同样的事情吗快速查看代码历史可以发现,这至少可以追溯到2010年11月,F#2.0——AFAIK在线提供的最早版本的代码。由于程序中的sizeof=4,它在交互中的大小真的是您的问题吗?请键入让F()=1;的行;;设g()=f();;设f()=2;;g();;你会发现g()仍然是1。因此,(以增量方式)向程序集添加了一个“new”f(),但“old”f()仍然存在,并被以前的增量代码引用。bananasareyellow,我会邀请@JYoung将答案作为答案发布,这样就可以在需要评分的地方给予评分。如果JYoung对声誉漠不关心并拒绝邀请,你可以自己发布答案并接受。继续吧,bananasareyellow,发布答案。你现在比我更了解它了。这并不能回答
的逻辑是否像它看起来那样是向后的问题。@ildjarn:你是对的,它不是。我将其标记为已回答,因为我的主要问题是由于虚拟字段的存在而导致结构的大小。这一测试仍然值得怀疑。
workAroundReflectionEmitBugs=tcConfig.isInteractive; // REVIEW: is this still required?