gpt4 book ai didi

generics - 为什么 F# 泛型结构有额外的 __dummy 字段?

转载 作者:行者123 更新时间:2023-12-02 15:06:29 25 4
gpt4 key购买 nike

使用 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

额外大小的原因似乎是存在整数 __dummy一般情况下的字段。再次使用 F# Interactive,您可以使用 typeof 看到这一点:

  • typeof<A>显示DeclaredFields = [|Int32 i|]
  • typeof<B<int>>显示DeclaredFields = [|Int32 i; Int32 __dummy|]

我不明白为什么会这样 __dummy已添加字段。

我认为负责添加它的代码在这里:

https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/ilxgen.fs

Line 6377显示此:

if requiresExtraField then 
yield mkILInstanceField("__dummy",cenv.g.ilg.typ_int32,None,ILMemberAccess.Assembly) ]

Line 6290是哪里requiresExtraField定义为:

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应该意味着该结构没有任何实例字段。但是编写的代码正在测试结构是否有任何实例字段,对于大多数结构(包括我的结构)来说,这都是正确的。我认为最终测试的最后一部分是是否有泛型类型参数。所以requiresExtraFieldfalse对于 type A (非通用)和 true对于 type B (通用类型)。

这是编译器错误还是代码正确?如果正确的话,那么这个__dummy的目的是什么? field ?有什么办法可以避免它吗?

作为另一项测试,我删除了唯一的实例字段,毫不奇怪,我得到了以下大小,显示 __dummy不再添加字段:

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

// sizeof<BB<int>> = 1
type BB<'T> = struct end

我想要使用值类型而不是引用类型的原因是,我将在数据结构中存储大量这些对象,而不仅仅是传递它们。

最佳答案

@jyoung 在我的原始帖子下面的评论中给出了解释。

requiresExtraField的最后一行还测试 cenv.opts.workAroundReflectionEmitBugs 。该标志似乎是在 fscopts.fs 中设置的。代码行是:

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

所以额外的问题__dummy字段仅出现在 F# Interactive 中。

关于generics - 为什么 F# 泛型结构有额外的 __dummy 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25848604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com