

Avoid a Void: eradicating null-pointer dereferencing - coliveira
http://lambda-the-ultimate.org/node/3558

======
BigZaphod
I've grown to really like Objective-Cs way of just ignoring the problem.
Sending a message to nil returns 0 (or a few variants on 0 depending on the
return type). No thrown runtime errors.

~~~
biohacker42
If you're smart enough to test for it returning 0, you're smart enough to test
if it is 0. And if you're stupid enough.. now it fails silently?

~~~
BigZaphod
In Objective-C you often end up with patterns like this:

    
    
      if ([[obj delegate] shouldThisDoSomething]) { ... stuff ... }
    

When calling "delegate" on obj, it might return nil if there isn't one set (or
if obj itself is nil). If it does return nil, sending "shouldThisDoSomething"
results in 0 (aka nil). nil == false, So "stuff" will never happen - which is
pretty much as expected in 99%* of cases. (* made up statistic)

This behavior, combined with a few rules like naming certain methods in a way
that asks permission rather than forbids an action, gets you an entire system
where you can almost completely forget about the issue while retaining
programmer control for the few special cases where it might matter and you can
test for it.

(Nil also sticks out like a sore thumb in the debugger if you're stepping
through and trying to figure out why something didn't work like you thought it
should.)

Aside: Nothing fails silently unless you never test it. It's just a matter of
how you're exposed to the failure. IMO, sending to nil resulting in 0/nil is
very good at eliminating a lot of if/else boilerplate for certain situations
which means less code cluttering my screen.

------
huhtenberg

      >
      >   x.f (args) 
      >
      > x, a reference, should normally denote an object but can 
      > be void, in which case the call will fail and produce an 
      > exception, often leading to a crash. *This is one of the 
      > main sources of instability in today's software.*
    

Says who ?

I have been routinely programming in C++ for the last 10 years and not only I
have not ran into this sort of bug in my own code, I have never seen it
encountered by anyone else in my vicinity. I understand they wanted to create
a dramatic backdrop for some cool new feature they are really proud of, but
conjuring facts out of thin air is not a way to do it.

~~~
gdp
I'm certainly familiar with this as an error. It's all-too-common:

    
    
      Bla x = someFunctionThatMightReturnNull();
    
      if(x.foo()) ...
    

Sure, people _should_ check the return value, but that check is often
forgotten, especially if x.foo() is some sort of validity or integrity
checking. It's an edge case.

And really, a proof by "I've-never-seen-it" seems like a weak justification
for accusing researchers of "conjuring facts out of thin air". If you're
actually interested, the article by Tony Hoare (which was also posted on LTU)
provides provides more concrete figures, if I recall. I think it's pretty well
understood as a very common error.

I'd be interested to know what you think common sources of instability are in
your experience?

~~~
huhtenberg
"This is one of the main sources of instability in today's software." is a
sweepingly bold statement, which is statistically inaccurate at best and
completely made-up at worst. Most likely it is simply applicable to a subset
of languages that do in fact make this sort of a mistake easy to make. These
languages do not however include either C or C++, which still account for a
lot today's software.

If you have a link for the Tony Hoare article, it'd be interesting to see what
its sampling base was.

~~~
gdp
You've never had a problem with a null pointer in C or C++? _Ever?_

You didn't answer my question, either. What do you think are the most common
sources of instability?

~~~
huhtenberg
> _You've never had a problem with a null pointer in C or C++? Ever?_

Not once we had a recorded bug caused by calling a class method on a null
pointer. If the code is operating with references, it requires some ingenuity
to return a null _reference_ from a function. And if the code operates with
pointers, the null checks are typically there. So, yeah, the p->foo() with p
being null is a very uncommon issue.

With regards to what are the common sources of instability are - based
strictly on my experience, the "instability" in C++ context typically comes
from not enforcing class invariants, or not adhering to the declared class
semantics. This clearly can come in a variety of forms and shapes, and it is
hardly possible to pinpoint specific language construct as a single most
common root of these problems. Also, I frankly do not remember when was the
last time we had an actual _crash_ in our production code. In C context the
sources of crashes vary, but more often than not they are caused by the side
effects of the functions, i.e. you have a data structure (pointed at or
allocated in some other fashion), you feed it to the function and this call
invalidates it, but you assume it does not. This sort of thing. Again, if
there are pointers, then any C programmer worth his salt will have either an
assert or a conditional right after where this pointer is initialized or
changed. I have _never_ seen a bug caused by calling a null function pointer,
and there is some code that makes a very extensive use of them.

Hopefully this answers your question.

Now, how about the link to that article ?

~~~
gdp
This is what I was thinking of (I misspoke, it's a presentation, rather than a
paper), but I recall seeing more than just an abstract somewhere. Perhaps I
was reading commentary:

<http://lambda-the-ultimate.org/node/3186>

From what you've said, it sounds like your code (and perhaps team?) are better
than average. You say yourself, you haven't had an actual crash since you can
remember. If you _were_ having crashes, then my money would be on them being
caused by one of: null references (which generally just falls into the
category of "not checking return values") and not accounting for edge cases.
But you don't have crashes, so all of this is a little bit speculative, isn't
it?

------
michaelneale
One approach I have seen people take in Objective C (and Scala) is to return a
Maybe "monad" from functions instead of the value directly - forces the caller
to match for cases when the actual value comes back versus the "non value".

~~~
BigZaphod
Are you sure you're thinking about Objective-C? Objective-C lets you send
messages to nil/0 which then return nil/0 silently - a feature used quite
often in all Objective-C code I've been exposed to and written myself in the 2
years I've been doing it.

~~~
michaelneale
Yes Obj-C - not sure of the details as it was only what people had showed me
(second hand knowledge)

