NullReferenceExceptions#

BradA poses an interesting question in his post on NullReferenceExceptions: "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?".

Off the top of my hat, I'd say it should be possible from the CLR perspective to call instance methods on null objects. As Brad says: a NullReferenceException occurs when you access instance state, i.e. when you use the implicit this reference that is passed in every instance method. If your method never uses that reference, I'd say you have no problem.

So I just tried that and it doesn't seem to work though (as I could have expected but still). Imagine a TestClass with a DoTest method that just writes a line to the console. If you look at the IL the C# compiler built for us, it says:

.locals (TestClass V_0)
L_0000: ldnull
L_0001: stloc.0
L_0002: ldloc.0
L_0003: callvirt TestClass.DoTest

As you see it just calls a method, the null reference is on the stack ready to be used as the this parameter, but it won't be used by the method call. So I'd say: rock on. But the runtime says: curtains close. Maybe it has something to do with the fact that the C# compiler always emits a virtual call (callvirt) even though I made TestClass sealed. And then it goes off looking for the object header to find the pointers to the baseclass or something, failing because there's no object header since there's no instance? I don't know, I'd have to dig deeper into the internals to find out but I think I'm on the right track here...

By the way, I've always loved the name "NullReferenceException" in sharp contrast to Java's "NullPointerException". Made me chuckle when I first saw that :-D

Update: as BradA pointed out in my comments, I seemed to be on the right track indeed. So I took his advice and changed the "callvirt" into a regular "call" and - lo and behold - it works! (So I'm asking "nobody" to do something for me and got away with it. I should try this for my dishes...)

A quick peek at Don Box's excellent Essential .NET Volume 1 (page 158-159) tells me why: a non-virtual call is just a jump to the exact place in memory where the JIT compiler placed the native code. No magic required. A virtual call however (which the C# compiler always creates, and I think somewhere in that book Don explains why that is - although I can't seem to remember right now...) will use the object's RuntimeTypeHandle to determine the proper method to call. Well, a RuntimeTypeHandle is instance state - which won't work on null objects. And so it fails. Yep, that about feels right...

Update: I won - woohoo :-) Thanks for the 2 .NET t-shirts and the note, Brad. Although I must say, I was really hoping for a job offer ;-)

Monday, February 23, 2004 7:59:47 PM (Romance Standard Time, UTC+01:00)
"NullPointerException" is for the "die hard" programmers, which we Java programmers really are ;-)

I would suggest "NoInstanceException" though... Since there is no object instance (wouldn't that make more sense?)

What's that email address again for Microsoft's/Sun's suggestion box? :-)
Doggi
Monday, February 23, 2004 11:16:42 PM (Romance Standard Time, UTC+01:00)
Pointers are for die hard programmers? Ah lame :-p Just admit to the fact that they advocated taking pointers out of the platform (the visible side of it anyway) but forgot to take it out of the class library. In a very visible place :-)

Hmmm but I do like that "NoInstanceException" thing: not bad! Although, if I'm right about calling methods on null objects, it should really be named NoInstanceStateException ;-)

The suggestion boxes can be found at nullornothinginvb@microsoft.com and nullpointer@java.com.
Tuesday, February 24, 2004 5:11:34 AM (Romance Standard Time, UTC+01:00)
Oh, you are getting very close... Want a hint? Maybe the C# compiler always forces you to use callvirt, but you can use notepad and ILASM to change the callvirt to another instruction that doesn't do the check...
Friday, February 27, 2004 4:32:18 PM (Romance Standard Time, UTC+01:00)
Consider, in C#, null is a keyword, and so "NullReferenceException" follows naturally. However, in the keyword-rich atmosphere of VB.NET, Nothing is the keyword meaning null, so "NothingReferenceException" seems appropriate.

In both languages, however, null and Nothing just mean, "there is no instance here", so I'd be onboard with a "NoInstanceException" which would follow naturally from null, Nothing, nil, 0, etc.
Dave
Comments are closed.
All content © 2008, Jelle Druyts
On this page

Recent Photos
www.flickr.com
This is a Flickr badge showing public photos from Jelle Druyts. Make your own badge here.
Advertising
Top Picks
Statistics
Total Posts: 344
This Year: 7
This Month: 0
This Week: 0
Comments: 522
Archives
Sitemap
Disclaimer
This is my personal website, not my boss', not my mother's, and certainly not the pope's. My personal opinions may be irrelevant, inaccurate, boring or even plain wrong, I'm sorry if that makes you feel uncomfortable. But then again, you don't have to read them, I just hope you'll find something interesting here now and then. I'll certainly do my best. But if you don't like it, go read the pope's blog. I'm sure it's fascinating.

Powered by:
newtelligence dasBlog 2.0.7226.0

Sign In