Thread overview
Blog Post: What Does Memory Safety Really Mean in D?
Aug 23, 2020
Paul Backus
Aug 23, 2020
Paul Backus
Aug 23, 2020
ag0aep6g
Aug 26, 2020
Dukc
Aug 26, 2020
Dennis
Aug 27, 2020
Paul Backus
Aug 27, 2020
Dennis
Aug 27, 2020
Paul Backus
Aug 27, 2020
Atila Neves
August 23, 2020
https://pbackus.github.io/blog/how-does-memory-safety-work-in-d.html

What exactly do we mean when we talk about "memory safety" in D? Is it the same thing as "undefined behavior"? Is it ever correct to mark and `extern(C)` function as `@trusted`? This post is my attempt to understand, and answer, questions like these.

If you think I've gotten anything wrong, please leave a reply--this is definitely an area where I'm still learning.
August 23, 2020
On Sunday, 23 August 2020 at 19:39:35 UTC, Paul Backus wrote:
> https://pbackus.github.io/blog/how-does-memory-safety-work-in-d.html

Oops, wrong link. Here's the correct one:

https://pbackus.github.io/blog/what-does-memory-safety-really-mean-in-d.html
August 23, 2020
On Sunday, 23 August 2020 at 19:40:57 UTC, Paul Backus wrote:
> https://pbackus.github.io/blog/what-does-memory-safety-really-mean-in-d.html

As far as I can tell, your understanding matches mine. Hopefully, that's a good thing.

I also agree that the "Memory Safety" page [1] isn't very helpful if you want to figure out what exactly "safety" means in D. It's more of a rough outline than a spec document. I consider the "Function Safety" section [2] (which you mention later) to be the real deal. If anyone wants to merge those two somewhat redundant pieces of the spec into one, that would be great.

[1] https://dlang.org/spec/memory-safe-d.html
[2] https://dlang.org/spec/function.html#function-safety
August 26, 2020
On Sunday, 23 August 2020 at 19:39:35 UTC, Paul Backus wrote:
> https://pbackus.github.io/blog/how-does-memory-safety-work-in-d.html
>
> What exactly do we mean when we talk about "memory safety" in D? Is it the same thing as "undefined behavior"? Is it ever correct to mark and `extern(C)` function as `@trusted`? This post is my attempt to understand, and answer, questions like these.
>
> If you think I've gotten anything wrong, please leave a reply--this is definitely an area where I'm still learning.

Good post.

I think there is a workaround to the variable access being always safe. Something like this in a dedicated module:

```
struct SystemVar(T, bool safeVal)
{  private T _var;
   static if (safeVal) @safe pure nothrow @nogc auto val()
   {  return _var;
   }
   else pure nothrow @nogc auto val(){return _var;}
   pure nothrow @nogc ref var(){return _var;}
}
```

August 26, 2020
On 8/26/20 10:29 AM, Dukc wrote:
> On Sunday, 23 August 2020 at 19:39:35 UTC, Paul Backus wrote:
>> https://pbackus.github.io/blog/how-does-memory-safety-work-in-d.html
>>
>> What exactly do we mean when we talk about "memory safety" in D? Is it the same thing as "undefined behavior"? Is it ever correct to mark and `extern(C)` function as `@trusted`? This post is my attempt to understand, and answer, questions like these.
>>
>> If you think I've gotten anything wrong, please leave a reply--this is definitely an area where I'm still learning.
> 
> Good post.
> 
> I think there is a workaround to the variable access being always safe. Something like this in a dedicated module:
> 
> ```
> struct SystemVar(T, bool safeVal)
> {  private T _var;
>     static if (safeVal) @safe pure nothrow @nogc auto val()
>     {  return _var;
>     }
>     else pure nothrow @nogc auto val(){return _var;}
>     pure nothrow @nogc ref var(){return _var;}
> }
> ```
> 

Nice idea. You need to mark everything as @system that should be -- this is a template, so the compiler is going to happily mark a lot (all?) of that as @safe.

-Steve
August 26, 2020
On Wednesday, 26 August 2020 at 14:29:46 UTC, Dukc wrote:
> I think there is a workaround to the variable access being always safe. Something like this in a dedicated module:
>
> ```
> struct SystemVar(T, bool safeVal)
> {  private T _var;
>    static if (safeVal) @safe pure nothrow @nogc auto val()
>    {  return _var;
>    }
>    else pure nothrow @nogc auto val(){return _var;}
>    pure nothrow @nogc ref var(){return _var;}
> }
> ```

This currently does not protect against:
- SystemVar.tupleof[0] (unless you have -preview=dip1000 set)
- __traits(getMember, SystemVar, "_var")
- aliasing (put SystemVar!int in a union with a plain int / cast SystemVar!int[] from int[])
- void initialization
August 27, 2020
On Sunday, 23 August 2020 at 19:39:35 UTC, Paul Backus wrote:
> https://pbackus.github.io/blog/how-does-memory-safety-work-in-d.html
>
> What exactly do we mean when we talk about "memory safety" in D? Is it the same thing as "undefined behavior"? Is it ever correct to mark and `extern(C)` function as `@trusted`? This post is my attempt to understand, and answer, questions like these.
>
> If you think I've gotten anything wrong, please leave a reply--this is definitely an area where I'm still learning.

Nice, thanks for the write-up.

I've been owing the D community a blog post on memory safety for a few months now. I started writing it, then DIP1028 happened and I wanted to wait for a while to bring it up again.
August 27, 2020
On Wednesday, 26 August 2020 at 15:34:26 UTC, Dennis wrote:
> On Wednesday, 26 August 2020 at 14:29:46 UTC, Dukc wrote:
>> I think there is a workaround to the variable access being always safe. Something like this in a dedicated module:
>>
>> ```
>> struct SystemVar(T, bool safeVal)
>> {  private T _var;
>>    static if (safeVal) @safe pure nothrow @nogc auto val()
>>    {  return _var;
>>    }
>>    else pure nothrow @nogc auto val(){return _var;}
>>    pure nothrow @nogc ref var(){return _var;}
>> }
>> ```
>
> This currently does not protect against:
> - SystemVar.tupleof[0] (unless you have -preview=dip1000 set)
> - __traits(getMember, SystemVar, "_var")
> - aliasing (put SystemVar!int in a union with a plain int / cast SystemVar!int[] from int[])
> - void initialization

Of course, you could also argue that these are things that shouldn't be allowed in @safe code to begin with--regardless of whether pointers are involved.

I think presenting @system variables as "protection" against memory corruption is the wrong way frame the discussion. The problem is that, currently, it is only possible to provide @safe access to certain kinds of data (discriminated unions, ref-counted pointers, etc.) by having @trusted code make assumptions about @safe code that must be manually verified.

There is, technically, nothing wrong with this. The D language spec does not place any restrictions on what assumptions you are allowed to make in @trusted code; it merely requires that you do the legwork to manually verify those assumptions if you want the compiler's automatic verification of @safe code to give the correct result.

What @system variables do is allow you to document, in machine-readable form, a particular kind of assumption ("this variable is never accessed directly from @safe code"), and have the compiler check it for you. In other words, they make @trusted code more *expressive* and *ergonomic*.
August 27, 2020
On Thursday, 27 August 2020 at 13:32:44 UTC, Paul Backus wrote:
> Of course, you could also argue that these are things that shouldn't be allowed in @safe code to begin with--regardless of whether pointers are involved.

I did not intend to argue anything with that post, I was just pointing out the limitations of the workaround if it were used today, in case Dukc wasn't aware of them.

> I think presenting @system variables as "protection" against memory corruption is the wrong way frame the discussion.

Is that still in reply to me (or DIP1035)? I don't recall saying something like that and don't want to get the wrong message across. I agree with everything you just wrote.
August 27, 2020
On Thursday, 27 August 2020 at 14:10:36 UTC, Dennis wrote:
> On Thursday, 27 August 2020 at 13:32:44 UTC, Paul Backus wrote:
>> Of course, you could also argue that these are things that shouldn't be allowed in @safe code to begin with--regardless of whether pointers are involved.
>
> I did not intend to argue anything with that post, I was just pointing out the limitations of the workaround if it were used today, in case Dukc wasn't aware of them.
>
>> I think presenting @system variables as "protection" against memory corruption is the wrong way frame the discussion.
>
> Is that still in reply to me (or DIP1035)? I don't recall saying something like that and don't want to get the wrong message across. I agree with everything you just wrote.

It was really a response to the discussion about DIP 1035 (and Andrei's critique in particular), using your post as an excuse to soapbox; apologies for the confusion.