Jump to page: 1 24  
Page
Thread overview
memory safety checks and trust
Apr 11, 2020
Adam D. Ruppe
Apr 11, 2020
Walter Bright
Apr 11, 2020
Johan
Apr 11, 2020
jeckel
Apr 12, 2020
Timon Gehr
Apr 13, 2020
Walter Bright
Apr 13, 2020
Timon Gehr
Apr 14, 2020
Walter Bright
Apr 14, 2020
aliak
Apr 14, 2020
Adam D. Ruppe
Apr 14, 2020
bachmeier
Apr 14, 2020
Walter Bright
Apr 14, 2020
Adam D. Ruppe
Apr 15, 2020
Walter Bright
Apr 15, 2020
Adam D. Ruppe
Apr 16, 2020
Walter Bright
Apr 16, 2020
Timon Gehr
Apr 13, 2020
Claude
Apr 14, 2020
Walter Bright
Apr 14, 2020
Walter Bright
Apr 15, 2020
Walter Bright
Apr 15, 2020
Max Samukha
Apr 16, 2020
Walter Bright
Apr 16, 2020
Max Samukha
Apr 16, 2020
Timon Gehr
Apr 16, 2020
Timon Gehr
Apr 16, 2020
Timon Gehr
Apr 16, 2020
Timon Gehr
Apr 11, 2020
Kagamin
Apr 15, 2020
mipri
April 11, 2020
```
void main() {
        int a;
        b ~= &a;
}

int*[] b;
```

trust.d(3): Error: copying & a into allocated memory escapes a reference to local variable a


(Interestingly, `b = [&a]` instead of ~= passes muster. What's the difference? Just another bug in this?)


But the inconsistency isn't why I'm posting right now, it is my fear that D is losing faith in me. There seems to be no way to say "trust me" to the compiler. Note that I'm not even using any switches to dmd, and adding @trusted had no effect.

One of the nice things about D is that I very rarely feel like I am fighting the language (unless I'm working under constraints like -w and @safe pure nothrow @nogc stuff, but that's why I just don't use those!). From low-level bit twiddling to high level "just make it work", the D language usually works with me, a few exceptions excluded - but when those happen, you can cast or whatever to tell it to trust me.

But this new thing... can I tell it to trust me? Is that just a bug too? Or will I have to trick it with extern(C) or asm or something?

(PS I actually changed the code somewhat and used a pointer to a static instance which worked for my specific case. But I'm a bit concerned about the future.)
April 10, 2020
On 4/10/2020 6:21 PM, Adam D. Ruppe wrote:
> ```
> void main() {
>          int a;
>          b ~= &a;
> }
> 
> int*[] b;
> ```
> 
> trust.d(3): Error: copying & a into allocated memory escapes a reference to local variable a
> 
> 
> (Interestingly, `b = [&a]` instead of ~= passes muster. What's the difference? Just another bug in this?)

You will get the error with -preview=dip1000. Since that will eventually be the default, it's not a bug.

You can get it to pass without error with the following:

  @system int* foo(int* p) { return p; }

  @system void test() {
        int a;
        b ~= &a;
        b ~= [foo(&a)];
  }

  int*[] b;

The compiler will inline foo(). I highly recommend annotating such code with &system.


> But the inconsistency isn't why I'm posting right now, it is my fear that D is losing faith in me. There seems to be no way to say "trust me" to the compiler. Note that I'm not even using any switches to dmd, and adding @trusted had no effect.
> 
> One of the nice things about D is that I very rarely feel like I am fighting the language (unless I'm working under constraints like -w and @safe pure nothrow @nogc stuff, but that's why I just don't use those!). From low-level bit twiddling to high level "just make it work", the D language usually works with me, a few exceptions excluded - but when those happen, you can cast or whatever to tell it to trust me.

If @system isn't letting you do what you need to do, let me know.
April 11, 2020
On Saturday, 11 April 2020 at 01:21:56 UTC, Adam D. Ruppe wrote:
> One of the nice things about D is that I very rarely feel like I am fighting the language (unless I'm working under constraints like -w and @safe pure nothrow @nogc stuff, but that's why I just don't use those!). From low-level bit twiddling to high level "just make it work", the D language usually works with me, a few exceptions excluded - but when those happen, you can cast or whatever to tell it to trust me.

Walter said there's now a third kind of safety for not annotated functions or something like that.
April 11, 2020
On Saturday, 11 April 2020 at 02:57:03 UTC, Walter Bright wrote:
> On 4/10/2020 6:21 PM, Adam D. Ruppe wrote:
>> ```
>> void main() {
>>          int a;
>>          b ~= &a;
>> }
>> 
>> int*[] b;
>> ```
>> 
>> trust.d(3): Error: copying & a into allocated memory escapes a reference to local variable a
>> 
>> 
>> (Interestingly, `b = [&a]` instead of ~= passes muster. What's the difference? Just another bug in this?)
>
> You will get the error with -preview=dip1000. Since that will eventually be the default, it's not a bug.
>
> You can get it to pass without error with the following:
>
>   @system int* foo(int* p) { return p; }
>
>   @system void test() {
>         int a;
>         b ~= &a;
>         b ~= [foo(&a)];
>   }
>
>   int*[] b;

The OP's point was that exactly this does not compile. Trivial to test online:
https://d.godbolt.org/z/i8WFcs

-Johan

April 11, 2020
On 4/11/20 6:01 AM, Johan wrote:
> On Saturday, 11 April 2020 at 02:57:03 UTC, Walter Bright wrote:
>> On 4/10/2020 6:21 PM, Adam D. Ruppe wrote:
>>> ```
>>> void main() {
>>>          int a;
>>>          b ~= &a;
>>> }
>>>
>>> int*[] b;
>>> ```
>>>
>>> trust.d(3): Error: copying & a into allocated memory escapes a reference to local variable a
>>>
>>>
>>> (Interestingly, `b = [&a]` instead of ~= passes muster. What's the difference? Just another bug in this?)
>>
>> You will get the error with -preview=dip1000. Since that will eventually be the default, it's not a bug.
>>
>> You can get it to pass without error with the following:
>>
>>   @system int* foo(int* p) { return p; }
>>
>>   @system void test() {
>>         int a;
>>         b ~= &a;
>>         b ~= [foo(&a)];
>>   }
>>
>>   int*[] b;
> 
> The OP's point was that exactly this does not compile. Trivial to test online:
> https://d.godbolt.org/z/i8WFcs

It does if you write it correctly:

b ~= foo(&a);

That was Walter's point. Once you get out of one expression, the checks stop.

You can do this too:

auto p = &;
b ~= p;

Note that a more robust argument for the OP's point is that you can easily make sure the allocation isn't used outside the function. What if you need scratch space to deal with things?

e.g.:

@system void test() {
   int *[] buf;
   int a;
   buf ~= &a; // Same error
}

How is &a escaping here?

-Steve
April 11, 2020
On Saturday, 11 April 2020 at 02:57:03 UTC, Walter Bright wrote:
> On 4/10/2020 6:21 PM, Adam D. Ruppe wrote:
>> ```
>> void main() {
>>          int a;
>>          b ~= &a;
>> }
>> 
>> int*[] b;
>> ```
>> 
>> trust.d(3): Error: copying & a into allocated memory escapes a reference to local variable a
>> 
>> 
>> (Interestingly, `b = [&a]` instead of ~= passes muster. What's the difference? Just another bug in this?)
>
> You will get the error with -preview=dip1000. Since that will eventually be the default, it's not a bug.
>
> You can get it to pass without error with the following:
>
>   @system int* foo(int* p) { return p; }
>
>   @system void test() {
>         int a;
>         b ~= &a;
>         b ~= [foo(&a)];
>   }
>
>   int*[] b;
>
> The compiler will inline foo(). I highly recommend annotating such code with &system.

FYI, you don't have to put @system. You can save yourself some time as @system is the default. This is equivalent:

   int* foo(int* p) { return p; }

   void test() {
         int a;
         b ~= &a;
         b ~= [foo(&a)];
   }

   int*[] b;






April 12, 2020
On 11.04.20 04:57, Walter Bright wrote:
> On 4/10/2020 6:21 PM, Adam D. Ruppe wrote:
>> ```
>> void main() {
>>          int a;
>>          b ~= &a;
>> }
>>
>> int*[] b;
>> ```
>>
>> trust.d(3): Error: copying & a into allocated memory escapes a reference to local variable a
>>
>>
>> (Interestingly, `b = [&a]` instead of ~= passes muster. What's the difference? Just another bug in this?)
> 
> You will get the error with -preview=dip1000. Since that will eventually be the default, it's not a bug.
> ...

Clearly there is a bug or bad design if the address of a`` escaping in `b ~= &a` and in `b = [&a]` are not treated the same. But like Adam I don't see why there should be such a check in @system/@trusted code at all. (I understand that there is a workaround, but that should not be required.)

Can we please settle on making @safe actually memory safe and @system/@trusted actually trust the programmer?
April 13, 2020
On 4/11/2020 7:43 PM, Timon Gehr wrote:
> Clearly there is a bug or bad design if the address of a`` escaping in `b ~= &a` and in `b = [&a]` are not treated the same.

They are treated the same with dip1000.

> But like Adam I don't see why there should be such a check in @system/@trusted code at all. (I understand that there is a workaround, but that should not be required.)
> 
> Can we please settle on making @safe actually memory safe and @system/@trusted actually trust the programmer?

Consider:

  @system int* pumpkin(int i) { return &i);

Should that give an error or not?

I.e. where does one draw the line?

April 13, 2020
On 13.04.20 09:50, Walter Bright wrote:
> 
>> But like Adam I don't see why there should be such a check in @system/@trusted code at all. (I understand that there is a workaround, but that should not be required.)
>>
>> Can we please settle on making @safe actually memory safe and @system/@trusted actually trust the programmer?
> 
> Consider:
> 
>    @system int* pumpkin(int i) { return &i; }
> 
> Should that give an error or not?
> ...

I don't see why not.

> I.e. where does one draw the line?

I think D has been in a pretty good place for a quite long time. Beyond straightforward parser/type system diagnostics that you can disable using explicit parentheses/type casts, only diagnose cases that have no legitimate use. You might not get this right, so it's probably a good idea to be open to the idea of removing/restricting diagnostics when people complain on the forums that their perfectly valid @system/@trusted code was rejected.

In @system/@trusted code, if you diagnose, the code should usually be wrong and if it is not, the workaround should have the same behavior as if the diagnostic had not been there in the first place (e.g., don't slow down debug builds).
April 13, 2020
On Monday, 13 April 2020 at 07:50:43 UTC, Walter Bright wrote:
> Consider:
>
>   @system int* pumpkin(int i) { return &i);
>
> Should that give an error or not?
>
> I.e. where does one draw the line?

I think it should not return an error. It is @system code, the programmer should be able to hack around as he wishes.

If he chooses safety, @safe is here.

For me the line is: @system code code should behave like plain old C. D just gives some extra expressiveness.

As a system-programmer, I wish to do with D what I can already do with C, faster, more elegantly.
« First   ‹ Prev
1 2 3 4