Questions from Tuesday’s talk

Thanks to everyone who attended our talk this morning. Apologies for the difficulties with the slides at the beginning. The slide sharing system we were using was being very unresponsive. Tomorrow should go more smoothly.

Speaking of which: tomorrow I’ll be talking about the top five things I wish every C# developer knew; number three will touch your heart, you’ll be shocked at number four and your dentist will hate number five. So tune in and learn how to improve your C# with one weird old trick. I’ll also post a schedule of events for the live talk on Thursday once I’ve got it.

The talk was recorded; when we have the recording and slides available I’ll post a link here.

Unfortunately we ran a little over – sorry – and did not have time for all the questions at the end. I’ll answer a few of the technical questions that did not get answered right now.

Continue reading

Live and in person

My colleagues and I are going to be giving three public presentations next week, two over the internet and one in person; if you’re interested in any of them, please join us!

On Tuesday January 28th 2014 from 8:30 to 9:30 AM Pacific Time my fellow “Bug Guy” Jon, my colleague Keri and I will be doing a webcast rather grandiosely entitled Breakthroughs in Semantic Analysis of C#. Thanks to Visual Studio Magazine for sponsoring this talk. This talk will be mostly focused on the work we’ve done to improve defect detection in C# in the latest version of Coverity’s analyzer.

On Wednesday January 29th 2014 from 8:30 to 9:30 AM Pacific Time the same crew will be doing a webcast entitled The Top Five Things Every C# Developer Should Know.[1. Because the internet loves Top N lists, you know.] There will be some overlap with the previous talk, but will be more focused on the common misconceptions and pitfalls that I see over and over again.

On Thursday January 30th 2014 from 3:00 to 7:00 PM Pacific Time Coverity founder/CTO Andy Chou and I will be doing a live in person presentation that is more or less the union of those two talks: If Your Code Could Speak, What Would It Say? at the San Jose Marriott at 301 S Market Street. Coverity CEO Anthony Bettencourt and Intuit Quality Manager John Ruberto will also be speaking. There will likely be a panel discussion and opportunities to network with other local tech geeks.

If you want to attend any or all of these, please click on the links above to go to the registration pages for each event. Hope to see you there!

If you can’t make it, the first two presentations will likely be recorded and archived somewhere; I’ll post a link when I know it. Some portions of the live presentation might also be recorded; I’m not sure.

More video

Here’s another fragment of the video interview I posted recently.

In this fragment I discuss the difference between analying IL and analyzing source code when trying to figure out if a defect exists. It turns out that you can get much better results by looking at the source code; there’s simply more information there. Being able to look at things like indentation and comments, where local variables were declared, and so on, makes a subtle but very real difference in the quality of the analysis.

This was an interesting video shoot for me. When I was at Microsoft I was used to Charles coming by with a hand-held camera and chatting with me off-camera, and then we’d pretty much post the whole thing. This was a much more involved production with lights, several camerapeople, multiple takes, and so on.[1. Also I find it amusing that they’ve changed the color saturation and tonality quite heavily; I’m not actually that pink, and the wall behind me is not green!]

ATBG: inconsistent equality

UPDATE from 2019: This post was originally on Coverity’s “Ask The Bug Guys” developer blog but that was taken down; an archived version is here. The formatting is still a bit messed up; I’ll fix it later.


Today’s episode of Ask The Bug Guys features a C# question from reader Jan:

Hi Bug Guys! We recently had a bug in our code comparing ints and shorts, where calling Equals() produced different results from using the == operator. Also, the behaviour of Equals() was not symmetric. Here’s a code snippet that reproduces the behaviour we observed:

int myInt = 1;
short myShort = 1;
Console.WriteLine(myInt == myShort);      // true
Console.WriteLine(myShort == myInt);      // true
Console.WriteLine(myInt.Equals(myShort)); // true
Console.WriteLine(myShort.Equals(myInt)); // false!

We were quite surprised when we found this. What explains this difference? Is it better to use ==instead of Equals() when comparing integer types?

Hi Jan! Thanks for the great question.

C# was designed to be a “pit of success” language: that is, a language where the obvious technique and the correct technique are the same. And for the most part, that’s true. Unfortunately, equality is one of the areas where there are significant pits of failure, and you’ve fallen right into one of them.

I’m going to add some additional cases to your program to illustrate a number of different equalities.

int myInt = 1;
short myShort = 1;
object objInt1 = myInt;
object objInt2 = myInt;
object objShort = myShort;
Console.WriteLine(myInt == myShort);      // scenario 1 true
Console.WriteLine(myShort == myInt);      // scenario 2 true
Console.WriteLine(myInt.Equals(myShort)); // scenario 3 true
Console.WriteLine(myShort.Equals(myInt)); // scenario 4 false!
Console.WriteLine(objInt1 == objInt1);    // scenario 5 true
Console.WriteLine(objInt1 == objShort);   // scenario 6 false!!
Console.WriteLine(objInt1 == objInt2);    // scenario 7 false!!!
Console.WriteLine(Equals(objInt1, objInt2));// scenario 8 true
Console.WriteLine(Equals(objInt1, objShort));// scenario 9 false!?!

What the heck? As it turns out, we have many different kinds of equality demonstrated here.

In scenarios one and two we must first determine what the == operator means. C# defines over a dozen different built-in == operators:

object == object
string == string
int == int
uint == uint
long == long
ulong == ulong
...

There is no int == short or short == int operators, so the unique best match on the list of built-in operators must be determined. It turns out that the best match is int == int. So the short is converted to int and then the two values are compared as numbers. They are therefore equal.

In scenario three we must first solve an overload resolution problem to determine what Equals means. The receiver is of type int and it has three methods named Equals:

Equals(objectobject// static method from object
Equals(object)         // virtual method from object
Equals(int)            // Implements IEquatable.Equals(int)

The first one we can eliminate because there are not enough arguments. Of the other two, the unique best method is the one that takes an int; it is always better to convert the short argument to intthan to object. Therefore we call Equals(int), which then compares the two integers again using value equality, so this is true.

In scenario four we again must determine what Equals means. The receiver is of type short which again has three methods named Equals

Equals(objectobject// static method from object
Equals(object)         // virtual method from object
Equals(short)          // Implements IEquatable.Equals(short)

Overload resolution eliminates the first because there are too few arguments and eliminates the third because there is no implicit conversion from int to short. That leaves short.Equals(object), which has the moral equivalent of this implementation:

bool Equals(object z)
{
  return is short && (short)z == this;
}

That is, for this method to return true the argument passed in must be a boxed short, and when unboxed it must be equal to the receiver. Since the argument is a boxed int, this returns false. There is no special gear in this implementation that says “well, what if I were to convert myself to the type of the argument and then compare?”

In scenarios five, six and seven operator overload resolution chooses the object == objectform, which is equivalent to a call to Object.ReferenceEquals. Clearly the two references are equal in case five and unequal in cases six and seven. Whether the values of the objects when interpreted as numbers are equal does not come into play at all; only reference equality is relevant.

In scenarios eight and nine operator overload resolution chooses the static method Object.Equals, which you can think of as being implemented like this:

public static bool Equals(object x, object y)
{
    if (ReferenceEquals(x, y)) return true;
    if (ReferenceEquals(x, null)) return false;
    if (ReferenceEquals(y, null)) return false;
    return x.Equals(y);
}

In scenario eight we have two references that are unequal and not null; therefore we call int.Equals(object), which as you would expect from our previous discussion of short.Equals(object) is implemented as the moral equivalent of:

bool Equals(object z)
{
  return is int && (int)z == this;
}

Since the argument is of type int it is unboxed and compared by value. In scenario nine the argument is a boxed short and so the type check fails and this is false.

Summing up: I’ve shown nine different ways that two things can be compared for equality; despite the fact that clearly in every case we have the number one on both sides of the equality, equality is true in only half the cases. If you think this is crazy and confusing, you’re right! Equality is tricky in C#.

I’ve been looking a lot at confusing cases for equality over my last year at Coverity; two of our checkers are specifically designed to find situations where you used the wrong kind of equality. But this article is long enough already and I’ve answered your question (I hope!), so I’ll discuss the specific cases that our checkers look for in another posting.

 

Ship it!

Today is a few days short of my first anniversary of starting work at Coverity. It has been an extremely fun, educational and challenging year. I wanted a change, and I got one in a lot of ways. Working at a rapidly-growing, ten-year-old, 300-person company is very different than working at an industry behemoth like Microsoft. Working in a downtown Seattle skyscraper is a pleasant change from crossing the bridge to Redmond every day. I’ve spent the last six months doing a lot more strategy and planning than writing code, which I hope to rebalance back towards the coding side for the next six months. Continue reading

What is “duck typing”?

Seriously, what is it? It’s not a rhetorical question. I realized this morning that I am totally confused about this.

First off, let me say what I thought “duck typing” was. I thought it was a form of typing.

So what is “typing”? We’ve discussed this before on this blog. (And you might want to check out this post on late binding and this post on strong typing.) To sum up:

Continue reading