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.