Regis Portalez
Regis Portalez

Reputation: 4860

Marshal.Sizeof and BitConverter.GetBytes behave differently on booleans

Let's consider this piece of code :

static void Main(string[] args)
{
    Console.WriteLine(Marshal.SizeOf(typeof(bool)));
    Console.WriteLine(String.Join(", ", BitConverter.GetBytes(true)));
}

if bool is 1 byte, I'd expect it to output

1
1

and if bool is 4 bytes (as an int), I'd expect

4
1, 0, 0, 0 // let's forget about the endianness

However, it outputs (in x64)

4
1

That's quite an issue for me in marshaling code. Who should I trust?

Please note that GetBytes takes a boolean as input : enter image description here

Upvotes: 2

Views: 330

Answers (2)

canton7
canton7

Reputation: 42235

Both of your ways of measuring the size of a bool are flawed.

Marshal.SizeOf is used to determine how much memory is taken when the given type is marshalled to unmanaged code. A bool is marshalled to a windows BOOL type, which is 4 bytes.

BitConverter.GetBytes(bool) is effectively implemented like this:

public static byte[] GetBytes(bool value) {
    byte[] r = new byte[1];
    r[0] = (value ? (byte)1 : (byte)0 );
    return r;
}

Source.

Therefore it always returns a single-element array.

What you're probably after is sizeof(byte), which "returns the number of bytes occupied by a variable of a given type" (MSDN). sizeof(bool) returns 1.

Upvotes: 5

Hubert
Hubert

Reputation: 403

The case here is that Marshal.SizeOf returns the size of an unmanaged type in bytes and unmanaged equivalent of boolean is a 4-byte Win32 BOOL type. see https://stackoverflow.com/a/6420546/3478025 for details

Upvotes: 0

Related Questions