NonNull template

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Apr 17 22:12:22 UTC 2025


On Thursday, April 17, 2025 11:36:49 AM MDT Dave P. via Digitalmars-d wrote:
> On Thursday, 17 April 2025 at 16:39:28 UTC, Walter Bright wrote:
> First to support classes, you’d have to make a slight change
> ```d
> struct NonNull(T)
> {
>      T p;
>      T ptr() { return p; }
>      alias this = ptr;
> }
> ```
>
> It works, but the syntax/defaults is backwards. Why does the
> unusual case of a nullable pointer get the nice syntax while the
> common case gets the `NonNull!(int*)` syntax? Who is going to
> write that all over their code?

I am in favor of making changes along the lines that Rikki is proposing so
that we can better handle failure in multi-threaded environments without
having to kill the entire program (and in addition, there are cases where
dereferencing null pointers is not actually memory-safe, because either that
platform doesn't protect it or a compiler like ldc or gdc will optimize the
code based on the fact that it treats null pointer dereferencing as
undefined behavior).

That being said, I honestly think that the concern over null pointers is
completely overblown. I can't even remember the last time that I encountered
one being dereferenced. And when I have, it's usually because I used a class
and forgot to initialize it, which blows up very quickly in testing rather
than it being a random bug that occurs during execution. So, if someone
feels the need to use non-null pointers of some kind all over the place, I'd
be concerned about how they're writing their code such that it's even a
problem - though it could easily be the case that they're just paranoid
about it, which happens with sometimes with a variety of issues and people.
And as such, I really don't think that it's all that big a deal if a wrapper
type is required to guarantee that a pointer isn't null. Most code shouldn't
need anything of the sort.

However, as I understand it, there _are_ memory-safety issues with null
pointers with ldc (and probably gdc as well) due to how they optimize. IIRC,
the core problem is that they treat dereferencing a null pointer as
undefined behavior, and that can have serious consequences with regards to
what the code does when there actually is a null pointer. dmd doesn't have
the same problem from what I understand simply because it's not as
aggressive with its optimizations. So, Walter's stance makes sense based on
what dmd is doing, but it doesn't necessarily make sense with D compilers in
general.

So, between that and the issues with platforms such as webasm, I am inclined
to think that we should treat dereferencing pointers like we treat accessing
elements of arrays and insert checks that the compiler can then optimize
out. And we can provide flags to change that behavior just like we do with
array bounds checking. But if we cannot guarantee that attempting to
dereference a null pointer is always @safe (and as I understand it, outside
of using dmd, we can't), then that's a hole in @safe. And no matter how rare
dereferencing null is or isn't in practice, we can't have holes in @safe and
have it actually give guarantees about memory safety.

- Jonathan M Davis






More information about the Digitalmars-d mailing list