Bug 8448 - `sizeof` IL opcode doesn't behave properly with respect to reference types
Summary: `sizeof` IL opcode doesn't behave properly with respect to reference types
Alias: None
Product: Runtime
Classification: Mono
Component: JIT ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2012-11-15 21:31 UTC by Jordan Earls
Modified: 2012-11-17 04:15 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

compiled test case (4.00 KB, application/x-msdos-program)
2012-11-15 21:31 UTC, Jordan Earls
sizeof IL library (required to run example program) (2.00 KB, application/x-msdos-program)
2012-11-15 21:31 UTC, Jordan Earls

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Jordan Earls 2012-11-15 21:31:11 UTC
Created attachment 2953 [details]
compiled test case

I believe I've found a bug concerning the `sizeof` opcode in Mono's IL implementation. Note: I'm NOT talking about the C# `sizeof()` operator. 

I made a tiny library in IL that has this method:

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

And then I tested it with:

	class MainClass
		public static void Main (string[] args)
			Console.WriteLine(BareMetal.SizeOf<Bar>()); //THIS
	struct Foo
		int a, b;
		byte c;
		object foo;
	class Bar
		string foo;
		string bar;
		AssemblyLoadEventArgs meh;
		DateTime d;
		byte[] Buffer;
		int mejhf;
		long fjke;
		byte jkfd;
		int fjkd;
		int jfke;

The output from this program is rather surprising for the sizeof Bar. Here is the full output (on my 64-bit machine):


I posted about this issue in the mailing list, but was told to look here: http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.sizeof%28v=vs.95%29.aspx

That link appears to indicate my IL is invalid, but it does verify. I believe that page is flat-out wrong also. 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"

Unless Mono is doing some really weird "inlining" of classes into value-types, then Mono is doing it wrong. This can cause a lot of problems because the sizeof opcode was created so that pointer arithmetic with arrays is possible with structures as the elements of the array. 

For reference, on .Net I get the expected value of either 4 or 8 for the size of "Bar" when running the program there (depends on platform of course)
Comment 1 Jordan Earls 2012-11-15 21:31:53 UTC
Created attachment 2954 [details]
sizeof IL library (required to run example program)
Comment 2 Jordan Earls 2012-11-15 21:39:38 UTC
The pages are identical, but here is the link to the actual .Net framework doc(not silverlight): http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.sizeof%28v=vs.110%29.aspx
Comment 3 Zoltan Varga 2012-11-17 04:15:11 UTC
Fixed in master.