tags:

views:

284

answers:

4

Hi, 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...

+1  A: 

This is actualy quite interesting. Because .NET uses as Big Endian even though on an underlying architecture, it's Little Endian.

Some interesting articles about .NET Endianness

Filip Ekberg
What do you mean by your second sentence? I suspect you're wrong, but you'll have to clarify what you mean before we can really tell.
Jon Skeet
Hmm, what? =) It is definately Little-Endian from the results above. I cant see how it can be anything else? Thx for the links, I took a look but couldnt really see an answer to the problem.
Ted
Also pretty easy to disprove with a "union" struct (explicit-layout)
Marc Gravell
@Jon, I might be wrong but as I've understood it. .NET Uses the same endianness on all achitectures even if, on intel, it's Little Endian or another Architecture where it's Big Endian. Am I wrong?
Filip Ekberg
Oh and this was more of a side-note + link collection rather than a correct answer which was provided by Marc.
Filip Ekberg
+1  A: 

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?

Jon Skeet
"it's a property rather than a variable" - actually, it is a static field.
Marc Gravell
@Marc: Yup, I'd just deleted that bit, having spotted it separately. Shame on me.
Jon Skeet
Jon: please read my "EDIT 2" above as an answer to your question. The behaviour is very strange...
Ted
+4  A: 

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.

Marc Gravell
Im am looking at it by breaking the code or Console.Writeline. That might be it, it isnt initialized when breaking the code, but it is initialized when I am using it in code, like Console.WriteLine.
Ted
Since he says it is false if he removes the line altogether, this leads me to think that he has put the breakpoint on the line before, which would trigger *before* BitConverter is used. I wonder what would happen if he just added another line after his call to ToInt16, which did nothing related to BitConverter, and breaked on that line instead, would it then show true?
Lasse V. Karlsen
Lasse: If the BitConverter.IsLittleEndian is used (like the Console.WriteLine) it is initializeed even before the line is executed. This, it is true even before BitConverter is used at all.
Ted
A: 

Like Marc says it seems to be a timing bug. Using the VS debugger to "peek" at the value at startup it returns false, but if I print it in a messagebox it returns true.

Erik