Null references redux
Daniel Keep
daniel.keep.lists at gmail.com
Sat Sep 26 20:51:58 PDT 2009
Jeremie Pelletier wrote:
> ...
>
> This is something for the runtime or the debugger to deal with. My
> runtime converts access violations on windows or segfaults on linux into
> exception objects, which unwind all the way down to main where it
> catches into the unhandled exception handler (or crash handler) and I
> get a neat popup with a "hello, your program crashed at this point, here
> is a backtrace with resolved symbols and filenames along with current
> registers and loaded modules, would you like a cup of coffee while you
> solve the problem?". I sent that crash handler to D.announce last week too.
See my long explanation that NPEs are only symptoms; very rarely do they
put up a big sign saying "what ho; the problem is RIGHT HERE!"
> The compiler won't be able to enforce *every* nonnull reference and
> segfaults are bound to happen, especially with casting. While it may
> prevent most of them, any good programmer would too, I don't remember
> the last time I had a segfault on a null reference actually.
I do. It took a day and a half to track it back to the source.
> I can see what the point is with nonnull references, but I can also see
> its not a bulletproof solution. ie "Object foo = cast(Object)null;"
> would easily bypass the nonnull enforcement, resulting in a segfault the
> system is trying to avoid.
Why lock the door when someone could break the window?
Why have laws when people could break them?
Why build a wall when someone could park a hydrogen bomb next to it?
Why have a typesystem when you could use casting to put the float
representation of 3.14159 into a void* and then dereference it?
Casting is not an argument against non-null references because casting
can BREAK ANYTHING.
"Doctor, it hurts when I hammer nails into my shin."
"So stop doing it."
> What about function parameters, a lot of parameters are optional
> references, which are tested and then used into functions whose
> parameters aren't optional. It would result in a lot of casts, something
> that could easily confuse people and easily generate segfaults.
So what you're saying is: better to never, ever do error checking and
just start fixing things after they've broken?
And why is everything solved via casting? Look: here's a solution
that's less typing than a cast, AND it's safe. You could even put
nonnull it in object.d!
T notnull(U : T?, T)(U obj)
{
if( obj is null ) throw new NullException;
return cast(T) obj;
}
void foo(Quxx o)
{
o.doStuff;
}
void foo(Quxx? o)
{
foo(notnull(o));
}
> Alls I'm saying is, nonnull references would just take the issue from
> one place to another.
YES.
THAT'S THE POINT.
It would take the error from a likely unrelated location in the
program's execution and put it RIGHT where the mistake initially occurs!
> Like Walter said, you can put a gas mask to ignore
> the room full of toxic gas, but that doesn't solve the gas problem in
> itself, you're just denyinng it exists. Then someday you forget about
> it, remove the mask, and suffocate.
>
> Jeremie
That's what NPEs are! They're a *symptom* of you passing crap in to
fields or functions. They very, VERY rarely actually point out what the
underlying mistake is.
More information about the Digitalmars-d
mailing list