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