| Thread overview | ||||||||
|---|---|---|---|---|---|---|---|---|
|
November 14, 2008 flagging runtime null dereferencing | ||||
|---|---|---|---|---|
| ||||
I know this has been brought up many times, but I think possibly the usefulness of this feature has been underestimated, and its cost overestimated.
Consider several points:
1. check for null needs to be done only when the source of the variable is
unknown.
2. segfaults can come from other sources, esp. memory corruption. It is
useful to distinguish null dereference (which is almost always an 'I forgot
to initialize' error).
3. check for null can easily be removed during release mode, especially if
it translates directly into an assert.
4. Yes, segfault is a loud error, but it's like hearing a gunshot from under
water. It's loud, but you have no idea where it's coming from, or whether a
null dereference is to blame. An assert is much more useful because it
tells you the line of code that fails. And please *please* don't tell me to
create a core dump, or use Dr. Watson. Not helpful.
I again propose that the D compiler in non-release mode inserts assert null checks where it can't prove that a pointer being dereferenced is not null, and removes those checks in release mode.
Example of "where it can't prove":
class C { void method();}
void fn(C c)
{
c.method(); // can't prove c is not null, insert check
c.method(); // know c is not null because it was checked above
}
In addition, I'd propose that the compiler does a static check to see if a null dereference definitely will happen. e.g:
C c;
c.method(); // should be a compile error.
Ran into this again, and again, had to spend too much time finding it.
-Steve
| ||||
November 14, 2008 Re: flagging runtime null dereferencing | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
>
> 4. Yes, segfault is a loud error, but it's like hearing a gunshot from under water. It's loud, but you have no idea where it's coming from, or whether a null dereference is to blame. An assert is much more useful because it tells you the line of code that fails. And please *please* don't tell me to create a core dump, or use Dr. Watson. Not helpful.
I don't suppose it helps much, but on *nix you can set a signal handler to get the stack pointer, etc, and generate a stack trace from there. I'm pretty sure this is possible on Win32 as well, but it would likely have to be in the SEH code in the runtime.
Sean
| |||
November 14, 2008 Re: flagging runtime null dereferencing | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:gfkui3$228r$1@digitalmars.com... > In addition, I'd propose that the compiler does a static check to see if a null dereference definitely will happen. e.g: > > C c; > c.method(); // should be a compile error. > > Ran into this again, and again, had to spend too much time finding it. > I would love to see this happen. Unfortunately, I'm guessing it would fall under the same category as getting a compile-time error on a missing return, that category being "Compile-time checks Walter doesn't want to implement because getting it flagged in *all* cases would require really fancy flow-control analysis". | |||
November 15, 2008 Re: flagging runtime null dereferencing | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> I know this has been brought up many times, but I think possibly the usefulness of this feature has been underestimated, and its cost overestimated.
>
> Consider several points:
>
> 1. check for null needs to be done only when the source of the variable is unknown.
> 2. segfaults can come from other sources, esp. memory corruption. It is useful to distinguish null dereference (which is almost always an 'I forgot to initialize' error).
> 3. check for null can easily be removed during release mode, especially if it translates directly into an assert.
> 4. Yes, segfault is a loud error, but it's like hearing a gunshot from under water. It's loud, but you have no idea where it's coming from, or whether a null dereference is to blame. An assert is much more useful because it tells you the line of code that fails. And please *please* don't tell me to create a core dump, or use Dr. Watson. Not helpful.
>
> I again propose that the D compiler in non-release mode inserts assert null checks where it can't prove that a pointer being dereferenced is not null, and removes those checks in release mode.
>
> Example of "where it can't prove":
> class C { void method();}
> void fn(C c)
> {
> c.method(); // can't prove c is not null, insert check
> c.method(); // know c is not null because it was checked above
> }
>
> In addition, I'd propose that the compiler does a static check to see if a null dereference definitely will happen. e.g:
>
> C c;
> c.method(); // should be a compile error.
>
> Ran into this again, and again, had to spend too much time finding it.
>
> -Steve
>
>
Hell, just the naive version of inserting assert( c !is null, ... ); before dereferences would be extremely awesome. I've already spent too much of my life on this crap.
| |||
November 15, 2008 Re: flagging runtime null dereferencing | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Chad J | Chad J wrote:
> Hell, just the naive version of inserting assert( c !is null, ... ); before dereferences would be extremely awesome. I've already spent too much of my life on this crap.
Yup, yup; agreed. Thankfully, Windows raises a structured exception for an AV, and using the Team0xf backtrace hack, it works just as good as a NPE raised in Java/C#.
| |||
November 15, 2008 Re: flagging runtime null dereferencing | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:gfkui3$228r$1@digitalmars.com... >I know this has been brought up many times, but I think possibly the usefulness of this feature has been underestimated, and its cost overestimated. I agree. <snip> > 3. check for null can easily be removed during release mode, especially if it translates directly into an assert. <snip> NullDerefError (or whatever we end up calling it) should probably be a separate exception class, just like the existing ArrayBoundsError and SwitchError. These are all things that are omitted when compiling in release mode. Stewart. -- My e-mail address is valid but not my primary mailbox. Please keep replies on the 'group where everybody may benefit. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply