Udostępnij za pośrednictwem


Not all “true” are created equal

 

During a review of some low level bit manipulation logic a developer raised a question about the correctness of a piece of code which allowed any arbitrary byte to be seen as a bool.  No one could recall if true was defined as not 0 or simply 1.  If it was the latter then the code was allowing for a large range of invalid bool values to be created.  A quick look at the CLI spec revealed the immediate answer (partition III section 1.1.2)

A CLI Boolean type occupies 1 byte in memory. A bit pattern of all zeroes denotes a value of false. A bit pattern with any one or more bits set (analogous to a non-zero integer) denotes a value of true.

A quick test backed up this particular assertion.  Any non-zero value is true and 0 is indeed false.  We took the test one step further and discovered, to the surprise of about half of us, that just because two bool values are true, doesn’t mean they’re equal.  

     class Program
    {
        [StructLayout(LayoutKind.Explicit)]
        struct Union
        {
            [FieldOffset(0)]
            internal byte ByteField;

            [FieldOffset(0)]
            internal bool BoolField;
        }

        static void Main(string[] args)
        {
            Union u1 = new Union();
            Union u2 = new Union();
            u1.ByteField = 1;
            u2.ByteField = 2;
            Console.WriteLine(u1.BoolField); // True
            Console.WriteLine(u2.BoolField); // True
            Console.WriteLine(u1.BoolField == u2.BoolField); // False
        }
    }

I was one of those who was surprised Smile

Comments

  • Anonymous
    August 27, 2012
    Which means that, somehow, comparing u1.BoolField to 'true' and u1 to u2 doesn't call the same code...

  • Anonymous
    August 27, 2012
    Keeping the same value of u2 as your sample:            bool b = true;            Console.WriteLine(u2.BoolField == b); // False            Console.WriteLine(u2.BoolField == true); // True I'm mind-blown!

  • Anonymous
    August 27, 2012
    The comment has been removed

  • Anonymous
    September 16, 2012
    Jared - You have a great blog; thanks for posting all of this! Your articles on DebuggerDisplay and similar attributes are really useful to my project. Just to let you know, I've made several modifications to your FlattenHierarchyProxy class (from blogs.msdn.com/.../flattening-class-hierarchies-when-debugging-c.aspx). A key modification is the ability to only "promote" (as I am calling it) members from base classes that you specify with attributes. I will be releasing the upgraded class on BitBucket. If you are interested, my blog is at http://www.mostthingsweb.com/. Thanks again for your work, Chris

  • Anonymous
    September 17, 2012
    Interesting.  I look forward to seeing the article on your blog

  • Anonymous
    October 09, 2012
    The repository is up: bitbucket.org/.../basememberpromotingproxy. Still probably needs lots of optimization, but the basic ideas are there. Please let me know if you would like to attributed a different way in the source.

  • Anonymous
    October 09, 2012
    Sorry for the double post. Here is the link to my article: www.mostthingsweb.com/.../basememberpromotingproxy-simplify-your-debugger-displays-of-nested-classes

  • Anonymous
    October 10, 2012
    I took a look at the project.  It looks very nice!