Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing public readonly members of structs in external assemblies

I'm getting a strange error when I use F# to read a public readonly member of a struct type defined in a C# assembly.

// C#: compile to Lib.dll
namespace Lib
{
    public class MyClass { public readonly int ReadonlyFoo; }

    public struct MyStruct
    {
        public readonly int ReadonlyFoo;
        public int WriteableFoo;
    }
}

// F#: compile to Client.exe
open Lib
let myClass = new MyClass()
printfn "MyClass.ReadonlyFoo = %x" myClass.ReadonlyFoo

let myStruct = new MyStruct()
printfn "MyStruct.WriteableFoo = %x" myStruct.WriteableFoo
printfn "MyStruct.ReadonlyFoo = %x" myStruct.ReadonlyFoo

When I compile Client.exe with F# 1.9.6.16, the last line gives the error:

"The address of the variable 'copyOfStruct' may not be used at this point"

The web is useless as of the time of this writing. It seems odd that one can read an immutable member of a class, and one can read a mutable member of a struct, but one can't read an immutable member of a struct. A workaround is easy enough, but I'm curious: is this a bug in the compiler?

Edit: I submitted a bug report to [email protected]

like image 342
Gabriel Avatar asked Sep 02 '09 15:09

Gabriel


1 Answers

Normally when people say 'it looks like a bug in the compiler' that is code for 'I don't know what I'm doing'. In this situation however, it does look to be like a bug.

The F# compiler makes a copy of structs behind the scenes in case they get mutated. (This is why even if you define a struct with mutable fields you must attribute the instance of that struct as mutable before you can update its fields.) It appears that the special magic going on behind the scenes forgets about 'readonly' struct fields.

While the internet and StackOverflow are a great place to ask for help about F#-related issues, please do let the F# team know about any bugs you find by emailing [email protected].

like image 114
Chris Smith Avatar answered Nov 15 '22 09:11

Chris Smith