Disallow null references in safe code?

Jonathan M Davis jmdavisProg at gmx.com
Sat Feb 1 23:46:54 PST 2014


On Saturday, February 01, 2014 19:40:26 Andrei Alexandrescu wrote:
> On 2/1/14, 7:29 PM, Jonathan M Davis wrote:
> > Sure, and there are other things that the compiler can do to catch null
> > dereferences (e.g. look at the first dereferencing of the pointer in the
> > function that it's declared in and make sure that it was initialized or
> > assigned a non-null value first), but the only way to catch all null
> > dereferences at compile time would be to always know at compile time
> > whether the pointer was null at the point that it's dereferenced, and
> > that can't be done.
> 
> What are you talking about? That has been done.

How so? All that's required is something like

auto ptr = foo();

if(bar()) //runtime dependent result
    ptr = null;

ptr.baz();

and there's no way that the compiler could know whether this code is going to 
dereference null or not. Sure, it could flag it as possible and thus buggy, 
but it can't know for sure. And an even simpler case is something like

auto ptr = foo();
ptr.baz();

The compiler isn't going to know whether foo returns null or not, and whether 
it returns null could depend on the state at runtime, making it so that it 
can't possibly know whether foo will return null or not.

And even if foo were as simple as

Bar* foo() { return null; }

the compiler would have to actually look at the body of foo to know that its 
return value was going to be null, and compilers that use the C compilation 
model don't normally do that, because they often don't have the body of foo 
available.

So, maybe I'm missing something here, and maybe we're just not quite talking 
about the same thing, but it's my understanding that it is not possible for 
the compiler to always know whether a pointer or reference is going to be null 
when it's dereferenced unless it's actually illegal for that pointer or 
reference type to be null (be it because of its type is non-nullable or an 
annotation marks it as such - which effectively then changes its type to non-
nullable). As soon as you're dealing with an actual, nullable pointer or 
reference, it's trivial to make it so that the compiler doesn't have any idea 
what the pointer's value could be and thus can't know whether it's null or 
not.

Sections of code which include the initialization or assignment of pointers 
which are given either new or null certainly can be examined by the compiler 
so that it can determine whether any dereferencing of that pointer that occurs 
could be dereferencing null, but something as simple as making it so that the 
pointer was initialized from the return value of  a function makes it so that 
it can't.

> > AFAIK, the only solution that guarantees that it catches all dereferences
> > of null at compile time is a solution that disallows a pointer/reference
> > from ever being null in the first place.
> 
> Have you read through that link?

Yes. And all I see is that @Nullable makes it so that some frameworks won't 
accept null without @Nullable, which effectively turns a normal Java reference 
into a non-nullable reference. I don't see anything indicating that the 
compiler will have any clue whether an @Nullable reference is null or not at 
compile time.

My point is that when a nullable pointer or reference is dereferenced, it's 
impossible to _always_ be able to determine at compile time whether it's going 
to dereference null. Some of the time you can, and using non-nullable, 
references certainly makes it so that you can, because then it's illegal for 
them to be null, but once a reference is nullable, unless the compiler knows 
the entire code path that that pointer's value goes through, and that code 
path is guaranteed to result in a null pointer or it's guaranteed to _not_ 
result in a null pointer, the compiler can't know whether the pointer is going 
to be null or not at the point that it's dereferenced. And you can't even 
necessarily do that with full program analysis due to the values potentially 
depending on runtime state. You could determine whether it _could_ be null if 
you had full program analysis, but you can't determine for certain that it 
will or won't be - not in all circumstances. And without full program 
analysis, you can't even do that in most cases, not with nullable references.

But maybe I'm just totally missing something here. I suspect though that we're 
just not communicating clearly enough for us to quite get what the other is 
saying. 

- Jonathan M Davis


More information about the Digitalmars-d mailing list