{"id":3623,"date":"2013-08-05T07:00:00","date_gmt":"2013-08-05T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/08\/05\/why-does-bitconverter-littleendian-return-false-on-my-x86-machine\/"},"modified":"2013-08-05T07:00:00","modified_gmt":"2013-08-05T07:00:00","slug":"why-does-bitconverter-littleendian-return-false-on-my-x86-machine","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130805-00\/?p=3623","title":{"rendered":"Why does BitConverter.LittleEndian return false on my x86 machine?"},"content":{"rendered":"<p>\nWelcome to CLR Week 2013,\nreturned from its\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2012\/07\/30\/10334554.aspx\">\ntwo-year hiatus<\/a>.\n<\/p>\n<p>\nA customer reported that when they checked with the debugger,\n<code>Bit&shy;Converter.Little&shy;Endian<\/code>\nreported <code>false<\/code>\neven though they were running on an x86 machine,\nwhich is a little-endian architecture.\n<\/p>\n<pre>\nushort foo = 65280;\n<i>65280<\/i>\nBitConverter.IsLittleEndian\n<i>false<\/i>\nBitConverter.GetBytes(foo)\n<i>{byte[2]}\n[0]: 0\n[1]: 255<\/i>\n<\/pre>\n<p>\nThe bytes are extracted in little-endian order,\ndespite the claim that the machine is big-endian.\n&#8220;I don&#8217;t get it.&#8221;\n<\/p>\n<p>\nI didn&#8217;t know the answer,\nbut I knew how to use a search engine,\nand a simple search quickly found\n<a HREF=\"http:\/\/stackoverflow.com\/q\/2023672\/\">this explanation<\/a>:\n<\/p>\n<p>\nReading a member from the debugger merely reads the value of the member\nfrom memory.\n<\/p>\n<p>\nThat simple statement hides the answer by saying what happens\nand leaving you to figure out what doesn&#8217;t happen.\nHere&#8217;s what doesn&#8217;t happen:\nReading a member from the debugger\n<i>does not execute the code to initialize that member<\/i>.\n<\/p>\n<p>\nIn the case of\n<code>Bit&shy;Converter<\/code>,\nthe <code>Little&shy;Endian<\/code> member\nis initialized by the static constructor.\nBut when are static constructors run?\nFor C#, static constructors are run\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/k9x6w0hc%28v=vs.80%29.aspx\">\nbefore the first instance is created or any static members are referenced<\/a>.\nTherefore, if you never create any <code>Bit&shy;Converter<\/code> objects\n(which you can&#8217;t since it is a static-only class),\nand if you never access any static members,\nthen its static constructor is not guaranteed to have run,\nand consequently\nanything that is initialized by the static constructor\nis not guaranteed to have been initialized.\n<\/p>\n<p>\nAnd then when you go looking at in the debugger,\nyou see the uninitialized value.\n<\/p>\n<p>\nWhy doesn&#8217;t the debugger execute static constructors\nbefore dumping a value from memory?\nProbably because the debugger wants to avoid surprises.\nIt would be weird if you tried to dump a value from the debugger\nand the program resumed execution!\n<\/p>\n<p>\nNow, when you ask the debugger to evaluate\n<code>Bit&shy;Converter.Get&shy;Bytes(foo)<\/code>,\nthe debugger has no choice but to execute application code,\nbut that&#8217;s okay because you explicitly told it to.\nBut let&#8217;s continue that debugging session:\n<\/p>\n<pre>\nushort foo = 65280;\n<i>65280<\/i>\nBitConverter.IsLittleEndian\n<i>false<\/i>\nBitConverter.GetBytes(foo)\n<i>{byte[2]}\n[0]: 0\n[1]: 255<\/i>\nBitConverter.IsLittleEndian\n<i>true<\/i> &larr; hey look\n<\/pre>\n<p>\nYour call to\n<code>Bit&shy;Converter.Get&shy;Bytes(foo)<\/code>\ncaused code to execute,\nand then the CLR said,\n&#8220;Okay, but before I call this member function, I am required\nto run the static constructor, because those are the rules,&#8221;\nand that resulted in the <code>Is&amp;shy:Little&shy;Endian<\/code>\nfield being initialized to <code>true<\/code>.\n<\/p>\n<p>\nThe customer replied,\n&#8220;Thanks.\nThe trick was finding the correct search terms.&#8221;\n<\/p>\n<p>\nI didn&#8217;t think my choice of search terms was particularly\ndevious.\nI simply searched for\n<a HREF=\"http:\/\/www.bing.com\/search?q=bitconverter.islittleendian+false\">\nbit&shy;converter.is&shy;little&shy;endian false<\/a>.\n<\/p>\n<p>\n<b>Bonus reading<\/b>:\n<a HREF=\"http:\/\/commandcenter.blogspot.com\/2012\/04\/byte-order-fallacy.html\">\nThe byte order fallacy<\/a> by\n<a HREF=\"http:\/\/en.wikipedia.org\/wiki\/Rob_Pike\">Rob Pike<\/a>.\n&#8220;Whenever I see code that asks what the native byte order is,\nit&#8217;s almost certain the code is either wrong or misguided.&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome to CLR Week 2013, returned from its two-year hiatus. A customer reported that when they checked with the debugger, Bit&shy;Converter.Little&shy;Endian reported false even though they were running on an x86 machine, which is a little-endian architecture. ushort foo = 65280; 65280 BitConverter.IsLittleEndian false BitConverter.GetBytes(foo) {byte[2]} [0]: 0 [1]: 255 The bytes are extracted in [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-3623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Welcome to CLR Week 2013, returned from its two-year hiatus. A customer reported that when they checked with the debugger, Bit&shy;Converter.Little&shy;Endian reported false even though they were running on an x86 machine, which is a little-endian architecture. ushort foo = 65280; 65280 BitConverter.IsLittleEndian false BitConverter.GetBytes(foo) {byte[2]} [0]: 0 [1]: 255 The bytes are extracted in [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3623","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=3623"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3623\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=3623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=3623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=3623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}