Memory safe in D

Steven Schveighoffer schveiguy at gmail.com
Wed Mar 13 18:20:12 UTC 2024


Just responding in general to the discussion here:

## Knowing 100% whether something is not null

This is a very difficult problem to solve. It can be automated to 
a degree, but I believe this is equivalent to the halting 
problem, so it's not solvable in P time.

However, many languages can prove *cases* of this using developer 
help (i.e. "unwrapping" a maybe-null value). This means that you 
have the drawback that your code has to be instrumented with null 
checks (written by you). And even if you do this, if it turns out 
the thing is null, you still have to handle it!

## Null happens

When you have an object that is null, and it shouldn't be, the 
means by which that null happened are no longer important. You 
need to handle it somehow.

- The path D takes is, let the hardware solve it.
- The path Java takes is to instrument dereferences on 
possibly-null variables and throw an exception if it's null.
- The path many other languages take is to force you to validate 
it's not null before using it.

These mechanisms all have their advantages and disadvantages.

D and Java have the advantage that you don't have to jump through 
hoops to prove things to the compiler. If a null pointer fault 
happens, it's because you have a bug in your code, but the 
language is your safety net here. It is still memory-safe in D 
since the hardware fault stops you from continuing execution, and 
any invalid pointers other than null should not be possible. In 
Java, it's obviously still memory safe.

For the other languages, you are forced to validate something is 
null or not null. This has the advantage that certain classes of 
bugs can be avoided at compile time, and in many cases, the code 
can be clearer where null pointers might exist. But the cost is 
that you may be forced to validate something that is obvious to 
the developer (but not the compiler). It adds to the tediousness 
of the language.

Relying on segfaults also has a further drawback that unless you 
happen to be running under a debugger, or have enabled 
core-dumps, you get no indication where in your program the issue 
happened. There is also no distinction between memory corruption 
and null pointer dereferencing. I think we should have a better 
outcome than this, we definitely can be more informative about 
what is happening.

The point I'm making is that it's not possible to ensure you 
never have to deal with null pointers. They happen. They even 
might happen in memory safe languages such as Rust. The 
difference is how you have to handle them. Handling them one way 
or another has benefits or drawbacks, but those are the tradeoffs 
you must make. It's important to note that in all these 
situations, the code is still *memory safe*.

-Steve


More information about the Digitalmars-d mailing list