Thread overview
Blog Post: What Does Memory Safety Really Mean in D?
Aug 23
ag0aep6g
Aug 26
Dukc
Aug 26
Dennis
Aug 27
Dennis
August 23
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
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
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
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
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
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
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
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
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
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.