Where’d that null
come from?
One of the most annoying things that can happen to a computer programmer is the dreaded NullPointerException
, or in C++, the segfault that occurs due to dereferencing a null pointer. The null pointer error has this ‘feature’ which makes it a ‘pleasure’ to debug: the source of the null can be arbitrarily far away from its use. I’ve come up with an interesting technique for tracking down the source:
- Use the
NullObject
pattern, so that the null pointer instead points at a null-behaving object. - Gift all
NullObject
s with an identification number. - Place an assertion that stops the debugger at the point when a
NullObject
with the same Id as the one which originally caused theNullPointerException
is constructed.
That first part will likely be the trickiest to pull off. In C++ there are several issues to consider. Is the null pointer of a user-created type (Thing*
) or built-in (int*
)? Is it easy to introduce a constructor which automatically changes Thing *t = null;
into Thing *t = new NullThing()
? Can this coercion also be done for subclasses (because a null subclass pointer can be type-converted to a base class pointer before the dereference)? Is it worth trying to change all Thing
pointers to Thing
references, just to make sure you catch everything?
One final issue: this technique will only work for deterministic code. Otherwise no guarantee can be made on the issuing of Id’s within the NullObject
constructor (easiest done with a global incrementing counter).