Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
If you have done much managed development you have run into a NullReferenceException more times that you’d care to count. The CLR throws this exception when you try to access instance state on null instance…
One of your internal customers suggested we give the type of instance that was null to help track down the errors. Not a bad idea, but Chris Brumme made it clear this is harder than you might expect…
The NullReferenceException occurs because an instruction like “call [eax+44]” or “mov edx, [esi+24]” has resulted in an access violation. We don’t retain nearly enough information to form a correspondence between a particular register being NULL at a particular EIP and the fact that a particular reference in the application was null. Especially since the EIP might be in a shared helper like a write barrier routine or an array helper. In those cases, we would have to perform a limited stack walk to get the effective EIP.
The machinery that would be required to improve this error message is huge. For the foreseeable future, you will have to rely on debuggers, or on FX code explicitly checking and throwing an appropriate NullArgumentException.
Oh well, back to the debugger!
But this does raise a number of interesting questions….
1) I said that we throw a NullReferenceException when you try to access instance “state” (eg a field). What if you have an instance method that does not touch any instance state (for example an instance method that just does a Console.WriteLine (“hello“)). Will you get a NullReferenceException when you call that? Why? Hint: It is one of those interesting differences between the CLR and the C# programming language.
2) As Chris implies above, the .NET Framework and WinFX generally do argument checking on all publicly exposed APIs. I continue to think this is a good thing to help you track to errors, but we do pay a very small perf price for these… Are they worth it?
3) Back in the day we had a number of long debates about the naming of NullReferenceException. As you VB folks know, there is no such this as Null in the VB world (expect maybe in the database)… VB uses the term “Nothing” for this concept. In retrospect should we have called in “NullReferenceOrNothingException”? Has anyone worked with a VB developer that was actually confused by this?
rewritting history here a little bit... I put “Empty” instead of “Nothing” when I first posted. Thanks to those of you who pointed it out.
Comments
- Anonymous
February 22, 2004
Hi Brad,
I don't advocate the "NullReferenceOrEmptyException" approach myself.
Otherwise, you'd have to extend the name for .NET COBOL developers etc., wouldn't you?
I think one, well-understood term should be used. The term "null" is the best one, in the general case, if you ask me. The fact that is also a keyword in some languages is a happy coincidence.
Martin
Incidentally, the equivalent of "null" in VB is "Nothing". - Anonymous
February 22, 2004
Null isn't a completely foreign reference to most VB devs, I would think. For one thing, if you've ever called a Win32 or other C function from VB, you've probably encountered vbNullString. And any VB dev who has SQL experience should have encountered NULL in that context as well.
And for those relatively (I hope) VB devs who have never used Win32, SQL, or learned any C-like language, picking up Null as an idiom for Nothing should be pretty easy anyway. - Anonymous
February 22, 2004
relatively few. Need more coffee... - Anonymous
February 23, 2004
I can't seem to get trackbacks working between DasBlog and .Text, I must be doing something wrong here. Anyway: I have an idea as to why it should be possible to call methods on null objects from the CLR point of view, but why it fails in C#:
http://jelledruyts.homeip.net/PermaLink.aspx?guid=92a28981-949c-450c-b3d0-d40a4bf6277d
Regarding the "NullReferenceOrEmptyException"-idea: please no. That just sounds awful, NullReferenceException is perfectly acceptable to me. The term "null" is and has been used for years to indicate a special place in memory, or a non-existant object, or a database row that has no data. "Emtpy" to me sounds like an existing object without any state (which could make sense sometimes). - Anonymous
February 23, 2004
Has anyone worked with a VB developer that was actually confused by this? I've worked with VB developers that get confused about LOTS of things... Never specifically this though :) - Anonymous
February 23, 2004
The comment has been removed - Anonymous
February 23, 2004
No, as a VB developer, I don't think the error message should have been called "...NullOrEmpty...". But then I'm one of those developers who thinks that the VB6 -> VB.Net 'Cleanup' didn't go far enough. I hate seeing, "...static, or shared in VB.Net..." in the documentation. As the saying goes, "It's the framework, stupid!" The closer my programming language resembles the framework, the less of a mind shift I have to go through when I'm switching between the two. - Anonymous
February 23, 2004
The comment has been removed - Anonymous
February 23, 2004
VB calls null "Nothing" (not Empty - that was what an uninitialised Variant was called), so if anything a VB-er would expect a "NothingReferenceException" - Anonymous
February 23, 2004
As far as #2 goes, PLEASE continue to do as much argument checking as possible. One of the most frustrating things about Win32 is that it lets you make mistakes that you don't find out about until something else possibly even unrelated goes wrong. Further, if you don't check all arguments, developers won't catch bugs and your hands will be tied (relatively anyway) when making new versions of the API. Better to catch everything immediately. And not just in a 'debug' mode either, because one thing you find is that some developers are criminally incompetent and wouldn't use a debug mode if their program ran fine in release but had errors in debug. Don't allow their kind to sneak by. - Anonymous
February 23, 2004
'A very small perf. price' That's another thing. It's clear there isn't a performance need by that statement. Don't introduce chaos for a 5% speed-up. Moore's Law will get you that in short order anyway, so it's needless, but development time will definitely be slowed by more than that trying to figure out what on earth is going on.. - Anonymous
February 23, 2004
Brad - Anonymous
February 23, 2004
You run into this exception more than you care to count? You have got to be kidding Brad, maybe VB programmers do but anybody who ever worked with C/C++ knows to check their object references (pointers) before they use them. But CLR's design guidelines actually make people use objects without checking if they have them, we've talked about this before (returning empty strings/arrays/collections versus returning nulls). And this is why I think that rule is just going to lead to worse code and you're going to have to think about things like this. - Anonymous
February 23, 2004
>Has anyone worked with a VB developer that was actually confused by this?
Never found one, many VB devs use both C# and VB so never found any problem with nullreference exception (indeed many warning and/or compiler messages reflects C# logic...). - Anonymous
February 23, 2004
>> VB uses the term “Empty” for this concept.
Actually, it uses Nothing. Empty is something quite different. - Anonymous
February 23, 2004
How does the CLR decide if a given AV should be converted to a NullReferenceException or not? Does it check that the referenced address was in fact 0? Does it look at the faulting instruction/address?
I hope it does at least check the referenced address. I'd hate to debug a process where an AV resulting from memory corruption was converted to a managed exception and silently handled. - Anonymous
February 23, 2004
Update: with a little help from Brad (and Don), I think I found the answer to his pop quiz :-)
http://jelledruyts.homeip.net/PermaLink.aspx?guid=92a28981-949c-450c-b3d0-d40a4bf6277d - Anonymous
February 24, 2004
- yes.
3) NullReferenceOrNothingException: unnecessary complexity.
Please keep the naming conventions and design guidelines as simple as possible. Otherwise, they will be ignored, and your efforts are in vain.
Anonymous
March 01, 2004
Absolutely - the small performance cost, saves me from far bigger problems on a regular basis. In addition its inspired our team to use arg checks throughout our code. They've never been a performance problem for us < 1% our time is spent doing arg checks.Anonymous
March 01, 2004
Argument CheckingAnonymous
November 10, 2007
PingBack from http://tanveerbadar.wordpress.com/2007/11/11/why-i-hate-vb/Anonymous
June 18, 2009
PingBack from http://patiocushionsource.info/story.php?id=2274