Why does F# generic struct have extra __dummy field?

Using F# Interactive, you can verify the following sizes:

// 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

The reason for the extra size seems to be the presence of an integer __dummy field in the generic case. Using F# Interactive again, you can see this using typeof:

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

I don’t understand why this __dummy field has been added.

I think the code responsible for adding it is here:

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

Line 6377 shows this:

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

Line 6290 is where requiresExtraField is defined:

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 assume that isEmptyStruct is supposed to mean that the struct does not have any instance fields. But the code as written is testing whether the struct does have any instance fields, which for most structs, including mine, is going to be true. I think the last part of the final test is whether there are any generic type parameters. So requiresExtraField is false for type A (not generic) and true for type B (generic type).

Is this a compiler bug, or is the code correct? If it is correct, then what’s the purpose of this __dummy field? Is there some way I can avoid having it?

As another test, I removed my one and only instance field, and not surprisingly, I got the following sizes, showing that the __dummy field was no longer added:

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

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

The reason I want to have a value type, rather than a reference type, is that I will be storing lots of these objects in my data structures, not just passing them around.

Does F# have generic arithmetic support?

Does F# have the same problem as C# where you can’t directly use arithmetic operators with generic T types? Can you write a generic Sum function that would return the sum of any value that supports th

Why does `struct sockaddr` contain a address family field?

Why does struct sockaddr contain an address family field? Isn’t the address family already fixed with the call to socket()?

Why does LayoutKind.Sequential work differently if a struct contains a DateTime field?

Why does LayoutKind.Sequential work differently if a struct contains a DateTime field? Consider the following code (a console app which must be compiled with unsafe enabled): using System; using Sys

Why does C have both . and -> for addressing struct members? [duplicate]

Possible Duplicate: Why does the arrow (->) operator in C exist? Why does C have both . and -> for addressing struct members? Is it possible to have such modified language syntax, where we can

Does struct hostent have a field “h_addr”?

I encountered the following code snapshot: struct hostent *hp; hp = my_gethostbyname(localhost); if (hp == NULL) { ls_syslog(LOG_ERR, I18N_FUNC_FAIL, fname, my_gethostbyname()); return -1; } strcpy(

Why does struct have two variable names in C/C++

In the below code why does the struct have two variable names? #include <sys/resource.h> int main (int argc, char **argv) { const rlim_t kStackSize = 64L * 1024L * 1024L; struct rlimit rl; //HER

Why is in F# a dummy symbol literal needed between pipe and when?

I am new to F# and fiddling just around with it. What get’s me is: let rec fact n = match n with | dummy when n < 2 -> 1 | _ -> n * fact (n – 1) let x = 6 printfn %d! = %d x (fact x) Why d

why sometimes you need to have a dummy object for event storage (JavaScript)

I don’t understand why sometimes you need to have a dummy object in JavaScript to store evetns, like following code. Metal.Gold = function() { var temp = $(<div>); //dummy object this.Submit =

Why does a field in a struct lose its value when a field in an identical class does not?

I have a Struct with a field in it that loses its value. I can declare the field static and that solves the problem. I can also just change struct to class (changing nothing else) and that also solves

Why does this struct definition add extra one byte of memory usage?

#include <stdio.h> typedef struct { short x,y; char type; } Tile; int main(int argc, const char *argv[]) { printf(%d/n,sizeof(short)); printf(%d/n,sizeof(char)); printf(%d/n,sizeof(Tile));

Answers

The explanation is given by @jyoung in the comments below my original posting.

The last line of requiresExtraField also tests cenv.opts.workAroundReflectionEmitBugs. This flag appears to be set in fscopts.fs. The line of code is:

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

So the problem of the extra __dummy field only occurs in F# Interactive.