Jump to page: 1 2
Thread overview
destroy and @safe
Jun 21, 2022
Antonio
Jun 21, 2022
Paul Backus
Jun 21, 2022
Adam D Ruppe
Jun 21, 2022
Antonio
Jun 21, 2022
Antonio
Jun 21, 2022
H. S. Teoh
Jun 21, 2022
H. S. Teoh
Jun 21, 2022
Paul Backus
Jun 21, 2022
H. S. Teoh
Jun 21, 2022
Antonio
June 21, 2022

I'm using explicitly destroy!false(obj) for a "deterministic" resources release.

I replicate the c# "using" pattern, or the python "with" pattern with my own "use" template supposing object are RAII

i.e.:

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

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)

June 21, 2022

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.

June 21, 2022

On 6/21/22 10:40 AM, Antonio wrote:

>

I'm using explicitly destroy!false(obj) for a "deterministic" resources release.

I replicate the c# "using" pattern, or the python "with" pattern with my own "use" template supposing object are RAII

i.e.:

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

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

June 21, 2022
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.
June 21, 2022

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"

June 21, 2022

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 :-)

June 21, 2022

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.

June 21, 2022

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

June 21, 2022
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.
June 21, 2022

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.

void foo(void delegate() @system dg) @safe {
   int *bar;
   @system void corrupt() { bar = cast(int *)0xdeadbeef;}
   dg = &corrupt;
   // can I call dg now?
}

-Steve

« First   ‹ Prev
1 2