www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - destroy and safe

reply Antonio <antonio abrevia.net> writes:
I'm using explicitly destroy!false(obj) for a "deterministic" 
resources release.


with my own "use" template supposing object are RAII

i.e.:

```d
Item[] items = query("...").use( (Answer a) =>
   a.rangify.map!(rowToItem).array()
);

```

The problem:

"use" can't be  safe because it contains a call to "destroy".

For better understanding of the idea, I include the "use" 
template code

```d
R use(R, T)(T obj, R delegate(T) fT)
{
   scope (exit)
     destroy!false(obj);

   return fT(obj);
}
```

What's the way to ensure  safe using destroy? (if possible)
Jun 21 2022
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 21 June 2022 at 14:40:41 UTC, Antonio wrote:
 The problem:

 "use" can't be  safe because it contains a call to "destroy".
`destroy` should be ` safe` as long as the destructor it's calling is ` safe`. If the destructor is ` system`, then the only way to call `destroy` in ` safe` code is to (1) determine the conditions necessary to call the destructor without violating memory safety, (2) ensure that those conditions are met (using compile time and/or runtime checks), and (3) wrap the call to `destroy` in a ` trusted` function. Since step (1) depends on the specific details of the destructor you want to call, I can't give any more specific advice unless you show a complete example that includes the destructor.
Jun 21 2022
next sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 21 June 2022 at 15:13:36 UTC, Paul Backus wrote:
 `destroy` should be ` safe` as long as the destructor it's 
 calling is ` safe`.
For classes, the current dmd+druntime implementation makes it impossible to determine statically if the destructor is safe or not. Structs I'm not sure about, the implementation might block it there too but idk.
Jun 21 2022
prev sibling parent reply Antonio <antonio abrevia.net> writes:
On Tuesday, 21 June 2022 at 15:13:36 UTC, Paul Backus wrote:

 If the destructor is ` system`, then the only way to call 
 `destroy` in ` safe` code is to (1) determine the conditions 
 necessary to call the destructor without violating memory 
 safety, (2) ensure that those conditions are met (using compile 
 time and/or runtime checks), and (3) wrap the call to `destroy` 
 in a ` trusted` function.

 Since step (1) depends on the specific details of the 
 destructor you want to call, I can't give any more specific 
 advice unless you show a complete example that includes the 
 destructor.
Thanks Paul. The problem appears when destroying a dpq2 query result object (not safe). I supose I can accept postgres PGClean(result) is safe "enought". My code starts to be a safe/ trusted mess (because external libraries). The only solution I have is to "wrap" them or to trust all code by default (I'm using vibe.d that forces safe code) Only as a comment: I can remember now when dart/flutter incorporated "sound null safety" and most of the third-party libraries where ported by authors... everybody assumed this will be the way of. D safe "optional" adoption is a problem As a personal advice, I would change the scoring system of the packages to penalize when they are not "safe"
Jun 21 2022
parent reply Antonio <antonio abrevia.net> writes:
On Tuesday, 21 June 2022 at 16:20:32 UTC, Antonio wrote:


 My code starts to be a  safe/ trusted mess (because external 
 libraries). The only solution I have is to "wrap" them or to 
 trust all code by default (I'm using vibe.d that forces  safe 
 code)

 Only as a comment: I can remember now when dart/flutter 
 incorporated "sound null safety" and most of the third-party 
 libraries where ported by authors... everybody assumed this 
 will be the way of.   D  safe "optional" adoption is a problem

 As a personal advice, I would change the scoring system of the 
 packages to penalize when they are not "safe"
Reading this I realize that the tone is out of place (especially because of the great disinterested effort behind the code of these libraries and the level of example they provide to those of us who are interested in the language). My apologies.
Jun 21 2022
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Tue, Jun 21, 2022 at 04:47:44PM +0000, Antonio via Digitalmars-d-learn wrote:
 On Tuesday, 21 June 2022 at 16:20:32 UTC, Antonio wrote:
 
 My code starts to be a  safe/ trusted mess (because external
 libraries).  The only solution I have is to "wrap" them or to trust
 all code by default (I'm using vibe.d that forces  safe code)
[...] IMO, that's a wrong design on the part of the library. The library ought to cater to user code, not the other way round; it should take advantage of safe user code where it can, but should not *force* the library user to use safe. The library code itself should be safe, but it ought to be callable from system code unless there's a good reason it can't be. I can foresee, though, a potential issue with delegates, since once you mark them safe, it forces user code to be safe. If you don't mark them and they default to system, then the library code that calls those delegates would also have to be system. This is why I've proposed in the past that safe functions should be allowed to call system delegates that they receive as arguments. The reasoning goes like this: if the delegate was in fact safe (i.e., it's a safe delegate passed to a system parameter -- safe is covariant with system), then there is no problem. If the delegate was system, then the caller can only have been called from system somewhere up the call stack ( safe code can't create system delegates), so we're also OK: if the caller was system, then we guarantee nothing anyway. However, Walter didn't seem convinced by this proposal. T -- This is not a sentence.
Jun 21 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/21/22 1:17 PM, H. S. Teoh wrote:
 On Tue, Jun 21, 2022 at 04:47:44PM +0000, Antonio via Digitalmars-d-learn
wrote:
 On Tuesday, 21 June 2022 at 16:20:32 UTC, Antonio wrote:

 My code starts to be a  safe/ trusted mess (because external
 libraries).  The only solution I have is to "wrap" them or to trust
 all code by default (I'm using vibe.d that forces  safe code)
[...] IMO, that's a wrong design on the part of the library. The library ought to cater to user code, not the other way round; it should take advantage of safe user code where it can, but should not *force* the library user to use safe. The library code itself should be safe, but it ought to be callable from system code unless there's a good reason it can't be. I can foresee, though, a potential issue with delegates, since once you mark them safe, it forces user code to be safe. If you don't mark them and they default to system, then the library code that calls those delegates would also have to be system. This is why I've proposed in the past that safe functions should be allowed to call system delegates that they receive as arguments. The reasoning goes like this: if the delegate was in fact safe (i.e., it's a safe delegate passed to a system parameter -- safe is covariant with system), then there is no problem. If the delegate was system, then the caller can only have been called from system somewhere up the call stack ( safe code can't create system delegates), so we're also OK: if the caller was system, then we guarantee nothing anyway. However, Walter didn't seem convinced by this proposal.
```d void foo(void delegate() system dg) safe { int *bar; system void corrupt() { bar = cast(int *)0xdeadbeef;} dg = &corrupt; // can I call dg now? } ``` -Steve
Jun 21 2022
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Tue, Jun 21, 2022 at 01:29:47PM -0400, Steven Schveighoffer via
Digitalmars-d-learn wrote:
 On 6/21/22 1:17 PM, H. S. Teoh wrote:
[...]
 This is why I've proposed in the past that  safe functions should be
 allowed to call  system delegates that they receive as arguments. The
 reasoning goes like this: if the delegate was in fact  safe (i.e., it's
 a  safe delegate passed to a  system parameter --  safe is covariant
 with  system), then there is no problem. If the delegate was  system,
 then the caller can only have been called from  system somewhere up the
 call stack ( safe code can't create  system delegates), so we're also
 OK: if the caller was  system, then we guarantee nothing anyway.
 However, Walter didn't seem convinced by this proposal.
```d void foo(void delegate() system dg) safe { int *bar; system void corrupt() { bar = cast(int *)0xdeadbeef;} dg = &corrupt; // can I call dg now? } ```
[...] Does the language allow you to declare a system delegate inside safe code? T -- Being able to learn is a great learning; being able to unlearn is a greater learning.
Jun 21 2022
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 21 June 2022 at 17:33:46 UTC, H. S. Teoh wrote:
 Does the language allow you to declare a  system delegate 
 inside  safe code?
Yes. This compiles: void main() safe { void delegate() system dg = () system { /* do scary stuff */ }; }
Jun 21 2022
parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Tue, Jun 21, 2022 at 06:28:14PM +0000, Paul Backus via Digitalmars-d-learn
wrote:
 On Tuesday, 21 June 2022 at 17:33:46 UTC, H. S. Teoh wrote:
 
 Does the language allow you to declare a  system delegate inside
  safe code?
Yes. This compiles: void main() safe { void delegate() system dg = () system { /* do scary stuff */ }; }
Hmph. That does put a damper on my idea. :-( T -- One reason that few people are aware there are programs running the internet is that they never crash in any significant way: the free software underlying the internet is reliable to the point of invisibility. -- Glyn Moody, from the article "Giving it all away"
Jun 21 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/21/22 1:33 PM, H. S. Teoh wrote:
 On Tue, Jun 21, 2022 at 01:29:47PM -0400, Steven Schveighoffer via
Digitalmars-d-learn wrote:
 ```d
 void foo(void delegate()  system dg)  safe {
     int *bar;
      system void corrupt() { bar = cast(int *)0xdeadbeef;}
     dg = &corrupt;
     // can I call dg now?
 }
 ```
[...] Does the language allow you to declare a system delegate inside safe code?
The code I wrote above compiles, even with dip1000. (note that I didn't actually call the delegate) -Steve
Jun 21 2022
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/21/22 10:40 AM, Antonio wrote:
 I'm using explicitly destroy!false(obj) for a "deterministic" resources 
 release.
 

 own "use" template supposing object are RAII
 
 i.e.:
 
 ```d
 Item[] items = query("...").use( (Answer a) =>
    a.rangify.map!(rowToItem).array()
 );
 
 ```
 
 The problem:
 
 "use" can't be  safe because it contains a call to "destroy".
 
 For better understanding of the idea, I include the "use" template code
 
 ```d
 R use(R, T)(T obj, R delegate(T) fT)
 {
    scope (exit)
      destroy!false(obj);
 
    return fT(obj);
 }
 ```
 
 What's the way to ensure  safe using destroy? (if possible)
destroy is safe if the destructor is safe. But your `use` function is being inferred as system. Why it's being inferred is likely not the destroy call (or maybe it's not the only problem). You delegate doesn't seem to be marked safe as well. To find the problems, mark `use` as safe, and see what it says. -Steve
Jun 21 2022
parent reply Antonio <antonio abrevia.net> writes:
On Tuesday, 21 June 2022 at 15:14:43 UTC, Steven Schveighoffer 
wrote:
 .... You delegate doesn't seem to be marked  safe as well.
Thanks a lot Steve, I didn't found a way (or example) to specify the delegate must be safe until I have found vibe.d.db.postgress implementation (that you maintain :-)
Jun 21 2022
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/21/22 12:33 PM, Antonio wrote:
 On Tuesday, 21 June 2022 at 15:14:43 UTC, Steven Schveighoffer wrote:
 .... You delegate doesn't seem to be marked  safe as well.
Thanks a lot Steve, I didn't found a way (or example) to specify the delegate must be safe until I have found vibe.d.db.postgress implementation (that you maintain :-)
I don't actually. That is Denis Feklushkin: https://github.com/denizzzka/vibe.d.db.postgresql I do maintain mysql-native. -Steve
Jun 21 2022