[OT] OT: Null checks.
Walter Bright
newshound2 at digitalmars.com
Sun May 4 01:19:53 UTC 2025
On 5/3/2025 3:10 PM, Timon Gehr wrote:
> No, it will not. It's UB in modern compiler backends, and there are increasingly
> important targets such as WASM where you can just write through a null pointer
> without any page protection. It also does not work in real mode, as well as some
> bare-metal/embedded systems.
On WASM, the null check would not be redundant, and so can be easily added by
the code generator.
As for real mode, that's 16 bit architecture which D does not (officially) support.
> Furthermore, there are no null checks when you pass a dereferenced null pointer
> to a `ref` parameter.
That's right. And if you access such a ref parameter, you get a seg fault. Not UB.
> In practice (outside your small DMC compiler backend box), you can only
> dereference a non-null pointer, so dereferencing a nullable pointer is actually
> explicitly one of the cases where you convert it to a non-nullable one...
```
int main()
{
int* p = (int*)0;
int& q = *p;
return q;
}
```
```
g++ x.c
./a.out
Segmentation fault (core dumped)
```
> Also, a segfault on some user's machine is a lot less useful than even a stack
> trace,
That's why the D runtime intercepts the seg fault and gives a stack trace. gdb
will also give a stack trace.
> and being able to collect some crash info in a `scope(failure)` or
> similar is even more useful. It can reduce a month-long heisenbug hunt into a 15
> minute fix.
I have a *lot* of experience chasing down null pointer violations in real mode
DOS. None of them took me a month. I think the worst one took 3 days. As soon as
I got my hands on a protected mode 286 system, I immediately switched all
development to it, because of the null pointer hardware protection. Big
productivity increase! After that, I only compiled the real mode version as the
very last thing after all tests passed.
(The worst heisenbug problems I had were the result of uninitialized variables.
Any changes at all to the code caused the problems to shift around. This is why
D initializes all variables.)
> `assert(0)` in druntime is a similarly frustrating experience.
Why? You can set assert(0) to do one of several things, including calling your
own custom handler. By default it'll tell you the file and line of the failure.
I use assert(0) all the time as a debugging tool.
> If there were a flag to enable null checks on any nullable pointer dereference,
> I would enable it immediately in all my projects.
I would be very curious how much larger and slower the resulting executables
would be.
P.S. Why would CPU designers put null checks in the hardware if it was so useless?
P.P.S. `scope(failure)` is not intended for catching `Error`, although it does.
There's a PR to fix it to only catch `Exception`, but that failed in the test suite.
More information about the Digitalmars-d
mailing list