Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IsLittleEndian field reports false, but it must be Little-Endian?

Tags:

c#

windows-7

Im running on a Intel computer (Win7 64-bit) and according to what I read Intel is using Little-Endian. I try this out in C# with the following code:

byte[] b2 = new byte[] { 0, 1 };
short b2short = BitConverter.ToInt16(b2, 0);

and b2short == 256 as expected from a Little-Endian.

Then I read that in .NET, the BitConverter.IsLittleEndian should reflect what endian the system is using, and when I check the variable in Visual Studio it reports false, ie it is NOT Little-Endian.

Does that have anything to do with 64-bit OS? Any ideas?


EDIT: My collegue, who sits across from me, did the same test (Win Vista 32-bit) and got the same results


EDIT 2: This is REALLY strange. Whenever I run the code, and break after the BitConverter did its thing, the IsLittleEndian == false. BUT, if I add the line Console.WriteLine(BitConverter.IsLittleEndian); afterwards it is TRUE:

byte[] b2 = new byte[] { 0, 1 };
short b2short = BitConverter.ToInt16(b2, 0);
Console.WriteLine(BitConverter.IsLittleEndian);
// Now the IsLittleEndian is true

But once I remove the Console.WriteLine it is false again.

I can also add that even if I break on the "Console.WriteLine" the IsLittleEndian == true, but if I remove the line altogether it is false.


EDIT 3: As Mark Gravell pointed out, this must be some timing-bug. If I use the variable BitConverter.IsLittleEndian it is initialized, if I dont (and look on it when breaking) its not initialized and thus false...

like image 392
Ted Avatar asked Jan 07 '10 21:01

Ted


People also ask

What does Little Endian mean?

Big-endian is an order in which the "big end" (most significant value in the sequence) is stored first, at the lowest storage address. Little-endian is an order in which the "little end" (least significant value in the sequence) is stored first.

Why do we use little endian?

The advantages of Little Endian are: It's easy to read the value in a variety of type sizes. For example, the variable A = 0x13 in 64-bit value in memory at the address B will be 1300 0000 0000 0000 . A will always be read as 19 regardless of using 8, 16, 32, 64-bit reads.

Is Windows big or little endian?

The following platforms are considered little endian: AXP/VMS, Digital UNIX, Intel ABI, OS/2, VAX/VMS, and Windows. On big endian platforms, the value 1 is stored in binary and is represented here in hexadecimal notation.

Is Intel Little Endian?

For example, Intel processors have traditionally been little-endian. Motorola processors have always been big-endian. Big-endian is an order in which the "big end" (the most-significant byte) is stored first. Little-endian is an order in which the "little end" (the least-significant byte) is stored first.


3 Answers

I wonder if this is a timing bug, perhaps related to "beforefieldinit"... how are you looking at the value? It is possible that the type-initializer (for BitConverter) isn't getting triggered by the VS debugger (which is peeking under the covers, so to speak). Especially since false is the default value for a field...

The IsLittleEndian static field is set in the static constructor; and the time that an initializer executes is... very hard to predict. If you are using a debugger, all bets are off. The only way to reliably check the value of this field is via code (when the CLR will run the initializer at some point before it is required):

bool isLittleEndian = BitConverter.IsLittleEndian; 

Don't trust the debugger / watch windows etc.

like image 83
Marc Gravell Avatar answered Sep 21 '22 21:09

Marc Gravell


Raymond Chen gives an expanded answer to the question here (mirror, with better formatting here).

The gist of it is that:

Reading a member from the debugger does not execute the code to initialize that member.

So when you look at the field in Visual Studio, it will report false because the static initializer has not yet run. However, if you use the field in code, the static initializer will run, causing the field to return the actual correct value.

like image 43
zastrowm Avatar answered Sep 23 '22 21:09

zastrowm


How are you checking it?

For example, run this short console app:

using System;

public class Test
{
    static void Main()
    {
        Console.WriteLine(BitConverter.IsLittleEndian);
    }
}

What does that print? Could you give details about what hardware and OS you're using?

like image 30
Jon Skeet Avatar answered Sep 25 '22 21:09

Jon Skeet