views:

104

answers:

4

So, a couple of questions, actually:

  1. An int (Int32) is specified to be (obviously) 32 bits. What about an int? (Nullable<int>)? My gut tells me that it would be 32 bits for the integer plus 8 more bits for the boolean, but perhaps the implementation is more intricate than that.
  2. I would have answered my own question using sizeof(int?); but as int? is a managed type this is not allowed. I understand that the size of a type may be platform-dependent, and that in the case of objects which contain references to other objects, a sizeof-like operation would be misleading. However, is there a way to get a "baseline" size (i.e., what the size of a newly instantiated instance would be) for a managed type, given the current environment?
+5  A: 

You can take a look in ildasm or Reflector.

If has two fields: a bool and a T, so probably 8 bytes (assuming 4 byte alignment).

Richard
Nice, learned something new with this one! It totally makes sense, but I had not considered alignment issues (I guess that's what happens when you enter software development late in the game, without a CS education).
Dan Tao
A: 

Consider Marshal.SizeOf method. It allows to obtain size of managed value types. It is strange, but looks like size of nullable type equals to size of their type parameter (size of int? equals to size of int, etc.)

STO
AFAIK you cannot marshal a nullable value. Therefore you are getting incorrect data.
Daniel Rose
+2  A: 

I found a treatment on exactly this question here, which includes code for a simple console application to test the memory usage.

Basically,

…This indicates that the nullable type wrapper requires 4 bytes of storage…

Jay
+3  A: 

It is rather important to never ask a question like this because you won't get a straight answer.

But since you did anyway: the minimum size is 0 bytes. Which you'll get when the JIT optimizer manages to keep the value in a CPU register. The next size is 2 bytes, for bool? and byte?, 1 byte for HasValue, another byte for the value. Which you'll rarely get because local variables must be aligned to an address that's a multiple of 4. The extra 2 bytes of padding simply will never be used.

The next size is 3 for short? and char?, you'll now get 1 byte of padding.

Big leap to the next one, int? requires 5 bytes but the padding increases that to 8.

Etcetera. You find this out by writing a bit of code like this:

        int front = 42;
        bool? center = null;
        int back = 43;
        Console.WriteLine("", front, center, back);

And looking at the machine code instructions with the debugger. Note the ebp register offsets. And beware that the stack grows down.

Hans Passant