[Mono-dev] Is the `sizeof` opcode doing the right thing?

Jordan Earls earlz at lastyearswishes.com
Wed Nov 14 03:04:52 UTC 2012


Hi, I've been messing with building a rather low-level datastructure
to avoid the Large Object Heap.

One thing this required of me was to write a very small library
directly in IL. The function I implemented is this:

    .method public static hidebysig
           default int32 SizeOf<T> ()  cil managed
    {
        .maxstack 1
	sizeof !!T
         ret
    }

And I then test this using this:

	class MainClass
	{
		public static void Main (string[] args)
		{
			Console.WriteLine(BareMetal.SizeOf<int>());
			Console.WriteLine(BareMetal.SizeOf<string>());
			Console.WriteLine(BareMetal.SizeOf<Foo>());
			Console.WriteLine(BareMetal.SizeOf<Bar>()); //this is of concern
			Console.ReadKey();
		}
	}
	struct Foo
	{
		int a, b;
		byte c;
		object foo;
	}
	class Bar
	{
		string foo;
		string bar;
		AssemblyLoadEventArgs meh;
		DateTime d;
	}

I got expected results in Microsoft's implementation with reference
values being stored as either 4 or 8 depending on platform

However, with Mono I get very surprising results. when getting the
sizeof `Bar`, it reports 32 on a 64-bit platform, when I would think
it would be either 4 or 8.

In the ECMA spec, on page 423 for partition III, it says "For a
reference type, the size returned is the size of a reference value to
the corresponding type, not the size of the data stored in objects
referred to by a reference value"

I think that language is a tiny bit ambiguous. Basically, does this
mean mono is being correct in that it's storing a "reference value" as
the entire class(an optimization?), or is Mono doing the wrong thing
in not returning just the size of the pointer? I'm not sure about the
Mono internals or anything, so I suspect that it *might* be conforming
to the spec, but I'd really like if someone could verify for this for
me.


More information about the Mono-devel-list mailing list