Pointers to managed objects (generics) -- recent change?

plynkusplynkus USMember

Greetings!

Currently running the following (via a couple of updates in the alpha channel this week, I believe):

Xamarin Studio
Version 4.1.11 (build 10)
Installation UUID: b577b744-52dd-4f14-848b-8dcc8a961c91
Runtime:
Mono 3.2.3 ((no/8d3b4b7)

After taking these, I noticed this weekend the following change to unsafe generics.
Methods of the following form previously compiled/functioned without issue...

    public static unsafe void Foo<T>(T[] data) where T : struct
    {
        fixed (T* t = &data[0])
        {
            // Do stuff.
        }
    }

...provided that T was qualified as above.

The methods in question now result in "Cannot take the address of, get the size of, or declare a pointer to a managed type T" errors, which I believe would have been the case before had the Ts not been so qualified as value types.

But now I get the errors no matter what, indicating:

(1) That it was illegal to do this in the first place, though the compiler previously allowed it.
(2) That it is not illegal to do this, and the compiler is now broken.

The non-generic cases appear to work with the expected behavior.
For example, the following emits the same error:

    public class MyType
    {
        int a;
    }

    public static unsafe void Foo(MyType[] data)
    {
        fixed (MyType* t = &data[0])
        {
            // Do stuff.
        }
    }

Change the above class to a struct and the error disappears.

Have we perhaps lost proper handling of "where T : struct"-like qualification here?

Any help is appreciated!

B

Posts

  • TheDriverTheDriver USMember

    It could be a 'side effect' of the new feature "Enable generic value type sharing".

    You may wish to try to disable that in the Advanced build options panel.

  • plynkusplynkus USMember

    It looks like this is actually a proper tidying up of the compiler, matches the MSVS behavior and the letter of the spec.

    While it is true that you can take said pointers to arrays of concrete structures, this is only true for "any user-defined struct type that contains fields of unmanaged types only."

    This is easily determined in the concrete case, but the "where T : struct" in the generic case does not fully guarantee this.

    It'd be nice if it would accept the generic and simply tell you you're in violation as you specialize for a given T (i.e. employ a struct with managed members), but oh well.

Sign In or Register to comment.