March 12

On Tuesday, 12 March 2024 at 03:28:54 UTC, Walter Bright wrote:

>

On 3/11/2024 12:43 PM, Steven Schveighoffer wrote:

>

The explanation is that D is expecting the memory hardware to fault when you dereference null. We know that this is not the case for all situations

In particular, when a constant is added to the null reference that is large enough to skip over the protected pages in the memory space.

I may have mentioned this before, but the way to fix this is in @safe code, before each reference with a constant offset that you know to be greater than one page, validate the root pointer is not null.

FWIW, I was actually talking about environments where the null page does not segfault, like in a kernel.

-Steve

March 12
> D's exception catchers do not catch Windows system exceptions for 64 bit code. Microsoft has not seen fit to document their 64 bit EH system.

This may help?
https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170


March 12

On Tuesday, 12 March 2024 at 03:12:44 UTC, Walter Bright wrote:

>

The default value for a class reference is null. Most objects need an "I'm not a valid object" value, and null is ideal for it because if it is dereferenced, a hardware segment fault is generated.

If a variable is initialized with void, that is something completely different. The variable winds up being set to garbage, as it is not initialized at all. This is why void initialization for references is only allowed in code marked @safe, and is usually used when top efficiency is required.

Consider what a null class reference is good for:

class ExtraInfo { ... }

struct S
{
    int a,b,c;
    ExtraInfo extra;
}

In my program, sometimes I need the extra info, but most of the time, not. Why have the compiler force an allocation for extra if it isn't used all the time? That just wastes time and memory.

You can write ExtraInfo extra = null;.

The reason ExtraInfo extra; is so confusing, and leads to posts like the one that started this thread, is because you're explicitly telling the compiler you want ExtraInfo. A new user of the language has no reason to expect it to be null. Someone wanting to optimize their code should have to be explicit that they want null and they're willing to deal with all the problems that can cause.

While it's true that your program is always going to crash, that's not a great solution unless you're testing every possible outcome for your program as you write it. It can take a long time for it to crash, possibly when you're busy with other things, and with no indication of why it crashed.

March 12
On 3/12/2024 6:57 AM, Steven Schveighoffer wrote:
> I may have mentioned this before, but the way to fix this is in `@safe` code, before each reference with a constant offset that you know to be greater than one page, validate the root pointer is not null.

I had thought the compiler already checked for that. But testing shows it does not. I wonder if there was a PR to remove it?

> FWIW, I was actually talking about environments where the null page does not segfault, like in a kernel.

I wonder why anyone would design it that way.

March 12
On 3/12/2024 1:26 AM, Alex wrote:
> On Tuesday, 12 March 2024 at 03:13:54 UTC, Walter Bright wrote:
>> On 3/11/2024 3:42 AM, Alex wrote:
>> Null references are not unsafe, that's why it is not in SafeD.
> 
> The Java has negative experience with null: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/
> In modern C++ preference is given to `std::optional`.
> For developer, who want make reliable software, it menas many rutinic checks for null. But mistakes are inevitable because of human factor. On other hand compiler can do it better (with 100% guarantee).

Yeah, I know about that article. It's very popular. I've written a sort of rebuttal:

https://www.digitalmars.com/articles/C-biggest-mistake.html

With Java, it is also not a memory safety issue when there's a null exception.


> In my opinion, Kotlin nullable types with compiler vaidation in compilation time is a powerfull feature:
> 
> ```d
> A? a; // without explicit initialization is ok here, because <type>? can hold null
> 
> a.run(); // compilation error, because can be null (the type of "a" is "A?")
> 
> if (a != null) {
>     a.run(); // ok, because can't be null in this branch (now type of "a" is "A")
> }
> ```

It is always better to catch null mistakes at compile time rather than runtime, but it isn't a memory safety issue.

March 12
On 3/12/2024 9:13 AM, Lance Bachmeier wrote:
> You can write `ExtraInfo extra = null;`.
> 
> The reason `ExtraInfo extra;` is so confusing, and leads to posts like the one that started this thread, is because you're explicitly telling the compiler you want ExtraInfo. A new user of the language has no reason to expect it to be null. Someone wanting to optimize their code should have to be explicit that they want null and they're willing to deal with all the problems that can cause.

Should it be initialized to - what? Let's say you're creating a linked list, with null signifying the end. If there aren't null references, you're going to have to have an "end" marker or some sort. So instead of checking for null, you have to check for the marker. If you forget to check for the marker, and the linked list goes off the end, then what? An exception is thrown? An assert fail()? How are these better? The program still fails at runtime.


> While it's true that your program is always going to crash, that's not a great solution unless you're testing every possible outcome for your program as you write it. It can take a long time for it to crash, possibly when you're busy with other things, and with no indication of why it crashed.

In my experience, the beauty of a null pointer exception is it almost always results in a direct indication to where the problem is, and it's one of the easiest bugs to fix.
March 12
On 3/12/2024 7:36 AM, An Pham wrote:
>> D's exception catchers do not catch Windows system exceptions for 64 bit code. Microsoft has not seen fit to document their 64 bit EH system.
> 
> This may help?
> https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170
> 
> 

I guess they did finally get around to documenting it. Thanks!
March 12

On Tuesday, 12 March 2024 at 17:53:41 UTC, Walter Bright wrote:

>

On 3/12/2024 9:13 AM, Lance Bachmeier wrote:

>

You can write ExtraInfo extra = null;.

The reason ExtraInfo extra; is so confusing, and leads to posts like the one that started this thread, is because you're explicitly telling the compiler you want ExtraInfo. A new user of the language has no reason to expect it to be null. Someone wanting to optimize their code should have to be explicit that they want null and they're willing to deal with all the problems that can cause.

Should it be initialized to - what? Let's say you're creating a linked list, with null signifying the end. If there aren't null references, you're going to have to have an "end" marker or some sort. So instead of checking for null, you have to check for the marker. If you forget to check for the marker, and the linked list goes off the end, then what? An exception is thrown? An assert fail()? How are these better? The program still fails at runtime.

I'm not sure I follow. As I understand it, ExtraInfo extra; and ExtraInfo extra = null; are exactly the same to the compiler (DMD generates identical assembly). My argument is that ExtraInfo extra; is confusing and therefore should not compile. That wouldn't restrict the language other than having to add "=null" to the declaration.

March 12

On Tuesday, 12 March 2024 at 17:42:14 UTC, Walter Bright wrote:

>

On 3/12/2024 6:57 AM, Steven Schveighoffer wrote:

>

I may have mentioned this before, but the way to fix this is in @safe code, before each reference with a constant offset that you know to be greater than one page, validate the root pointer is not null.

I had thought the compiler already checked for that. But testing shows it does not. I wonder if there was a PR to remove it?

I don't know if that was ever present.

> >

FWIW, I was actually talking about environments where the null page does not segfault, like in a kernel.

I wonder why anyone would design it that way.

e.g.: https://en.wikipedia.org/wiki/Zero_page#Interrupt_vectors

-Steve

March 12
When I first learned Java, I did not realize that the classes were reference types. I thought they were values (like in C++). I found the coding examples baffling, until I finally realized they were reference types.

I don't think there's a way around needing to understand the difference between a reference type and a value type.