digitalmars.D.learn - Temporary trusted scope
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (4/4) Dec 18 2018 What's the preferred way of creating a temporary @trusted scope
- Jonathan M Davis (14/18) Dec 18 2018 Unfortunately, D does not currently have a way to do that. Only function...
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (3/9) Dec 18 2018 Is there a performance hit when using this?
- rikki cattermole (4/13) Dec 18 2018 Yes except for ldc with -O3.
- Jonathan M Davis (12/25) Dec 18 2018 Really? I would have thought that that would be a pretty obvious
- Kagamin (3/9) Dec 19 2018 AFAIK, it was added.
- rikki cattermole (2/4) Dec 19 2018 Assembly doesn't lie.
- Jonathan M Davis (8/12) Dec 19 2018 I'm not saying that you're wrong, just expressing surprise. I've never
- rikki cattermole (3/18) Dec 19 2018 I agree, this would be a very simple AST rewrite. Would be well worth
- Kagamin (3/4) Dec 19 2018 ldc with -O2 generates the same code.
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (20/22) Dec 18 2018 Jonathan's idea might also be encapsulated in a function, just
- Steven Schveighoffer (8/34) Dec 18 2018 Wow, I really like this. The only real problem is that one generally
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (4/9) Dec 18 2018 Very nice! What about proposing this for inclusion into
- H. S. Teoh (15/51) Dec 18 2018 [...]
- Steven Schveighoffer (15/64) Dec 18 2018 You may not be realizing what the point of this is. Essentially, you
- aliak (14/50) Dec 18 2018 I've been gathering assume related stuff like this in a lib under
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (7/18) Dec 19 2018 While @trusted wouldn't work, it could be named 'trusted' instead
What's the preferred way of creating a temporary trusted scope without writing a separate function? Similar to Rust's unsafe { /* unsafe stuff here */ }
Dec 18 2018
On Tuesday, December 18, 2018 3:14:50 AM MST Per Nordlw via Digitalmars-d- learn wrote:What's the preferred way of creating a temporary trusted scope without writing a separate function? Similar to Rust's unsafe { /* unsafe stuff here */ }Unfortunately, D does not currently have a way to do that. Only functions can be marked with trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () trusted { doUnsafe(); }(); or auto result = () trusted { getUnsafe:() }(); So, it's less than ideal, but it gets us close, and unless the code is long enough that maybe it should be in its own function, it's better than declaring a nested function, let alone declaring an entirely separate function at module scope. - Jonathan M Davis
Dec 18 2018
On Tuesday, 18 December 2018 at 10:42:51 UTC, Jonathan M Davis wrote:Unfortunately, D does not currently have a way to do that. Only functions can be marked with trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () trusted { doUnsafe(); }();Is there a performance hit when using this?
Dec 18 2018
On 19/12/2018 1:34 AM, Per Nordlöw wrote:On Tuesday, 18 December 2018 at 10:42:51 UTC, Jonathan M Davis wrote:Yes except for ldc with -O3. But it is a function not a delegate so it should be all nicely prefetched and ready to go. So I wouldn't worry about it too much.Unfortunately, D does not currently have a way to do that. Only functions can be marked with trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () trusted { doUnsafe(); }();Is there a performance hit when using this?
Dec 18 2018
On Tuesday, December 18, 2018 5:42:12 AM MST rikki cattermole via Digitalmars-d-learn wrote:On 19/12/2018 1:34 AM, Per Nordlw wrote:Really? I would have thought that that would be a pretty obvious optimization (especially if inlining is enabled). I suppose that it doesn't entirely surprise me if dmd does a poor job of it, but I would have expected ldc to do better than that. I would think that such an improvement would be pretty low-hanging fruit for adding to dmd's optimizer though. If not, it sounds like further justification for adding a feature for this rather than having to use a lambda. Aside from that though, the lambda trick is simple enough that it wouldn't surprise me if Walter and Andrei's response to such a DIP would be to just use the lambda trick. - Jonathan M DavisOn Tuesday, 18 December 2018 at 10:42:51 UTC, Jonathan M Davis wrote:Yes except for ldc with -O3. But it is a function not a delegate so it should be all nicely prefetched and ready to go. So I wouldn't worry about it too much.Unfortunately, D does not currently have a way to do that. Only functions can be marked with trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () trusted { doUnsafe(); }();Is there a performance hit when using this?
Dec 18 2018
On Wednesday, 19 December 2018 at 06:11:48 UTC, Jonathan M Davis wrote:Really? I would have thought that that would be a pretty obvious optimization (especially if inlining is enabled). I suppose that it doesn't entirely surprise me if dmd does a poor job of it, but I would have expected ldc to do better than that. I would think that such an improvement would be pretty low-hanging fruit for adding to dmd's optimizer though.AFAIK, it was added.
Dec 19 2018
On 19/12/2018 7:11 PM, Jonathan M Davis wrote:Really? I would have thought that that would be a pretty obvious optimization (especially if inlining is enabled).Assembly doesn't lie.
Dec 19 2018
On Wednesday, December 19, 2018 1:19:42 AM MST rikki cattermole via Digitalmars-d-learn wrote:On 19/12/2018 7:11 PM, Jonathan M Davis wrote:I'm not saying that you're wrong, just expressing surprise. I've never checked to see what code actually got generated. But I do think that it's something that the compiler should be smart enough to do even if it isn't currently that smart, and the fact that it isn't is most defintely not a good thing. - Jonathan M DavisReally? I would have thought that that would be a pretty obvious optimization (especially if inlining is enabled).Assembly doesn't lie.
Dec 19 2018
On 20/12/2018 5:02 AM, Jonathan M Davis wrote:On Wednesday, December 19, 2018 1:19:42 AM MST rikki cattermole via Digitalmars-d-learn wrote:I agree, this would be a very simple AST rewrite. Would be well worth doing since its a common-ish pattern.On 19/12/2018 7:11 PM, Jonathan M Davis wrote:I'm not saying that you're wrong, just expressing surprise. I've never checked to see what code actually got generated. But I do think that it's something that the compiler should be smart enough to do even if it isn't currently that smart, and the fact that it isn't is most defintely not a good thing. - Jonathan M DavisReally? I would have thought that that would be a pretty obvious optimization (especially if inlining is enabled).Assembly doesn't lie.
Dec 19 2018
On Tuesday, 18 December 2018 at 12:42:12 UTC, rikki cattermole wrote:Yes except for ldc with -O3.ldc with -O2 generates the same code.
Dec 19 2018
On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote:What's the preferred way of creating a temporary trusted scope without writing a separate function?Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { trusted auto unsafe(T...)(T args) { return fn(args); } } system void fun(int n) { writeln("foo!"); } safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); } -- Simen
Dec 18 2018
On 12/18/18 6:29 AM, Simen Kjærås wrote:On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote:Wow, I really like this. The only real problem is that one generally searches for trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with trusted (and specify the mangle). But any decent compiler should get rid of any overhead there. -SteveWhat's the preferred way of creating a temporary trusted scope without writing a separate function?Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { trusted auto unsafe(T...)(T args) { return fn(args); } } system void fun(int n) { writeln("foo!"); } safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); }
Dec 18 2018
On Tuesday, 18 December 2018 at 13:52:29 UTC, Steven Schveighoffer wrote:Very nice! What about proposing this for inclusion into `std.typecons` or `std.meta`?template unsafe(alias fn) { trusted auto unsafe(T...)(T args) { return fn(args); } }
Dec 18 2018
On Tue, Dec 18, 2018 at 08:52:29AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:On 12/18/18 6:29 AM, Simen Kjrs wrote:[...] I'm not so sure I like this. trusted bits of code really should have a safe API that cannot be called in a way that breaks safe. Being able to essentially "cast away" safe for arbitrary bits of code seems to me to be a rather scary, underhanded way of undermining safe. OTOH, if your function is very large and only isolated bits are non- safe, then a construct like this one could help, by making the code less noisy, and ensuring that the other parts of the code still remain safe. (Though IMO in such cases the function may be better refactored to encapsulate away the trusted bits in functions with safe APIs, and keep the safe code all in one place.) T -- MASM = Mana Ada Sistem, Man!On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlw wrote:Wow, I really like this. The only real problem is that one generally searches for trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with trusted (and specify the mangle). But any decent compiler should get rid of any overhead there.What's the preferred way of creating a temporary trusted scope without writing a separate function?Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { trusted auto unsafe(T...)(T args) { return fn(args); } } system void fun(int n) { writeln("foo!"); } safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); }
Dec 18 2018
On 12/18/18 10:53 AM, H. S. Teoh wrote:On Tue, Dec 18, 2018 at 08:52:29AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:You may not be realizing what the point of this is. Essentially, you replace your inline trusted lambda with this call. It's just nicer syntax/usage without all the extra parentheses. Other than that, every usage of it would need as much scrutiny as a trusted lambda.On 12/18/18 6:29 AM, Simen Kjærås wrote:[...] I'm not so sure I like this. trusted bits of code really should have a safe API that cannot be called in a way that breaks safe. Being able to essentially "cast away" safe for arbitrary bits of code seems to me to be a rather scary, underhanded way of undermining safe.On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote:Wow, I really like this. The only real problem is that one generally searches for trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with trusted (and specify the mangle). But any decent compiler should get rid of any overhead there.What's the preferred way of creating a temporary trusted scope without writing a separate function?Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { trusted auto unsafe(T...)(T args) { return fn(args); } } system void fun(int n) { writeln("foo!"); } safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); }OTOH, if your function is very large and only isolated bits are non- safe, then a construct like this one could help, by making the code less noisy, and ensuring that the other parts of the code still remain safe. (Though IMO in such cases the function may be better refactored to encapsulate away the trusted bits in functions with safe APIs, and keep the safe code all in one place.)Yes, exactly. The point of trusted lambdas are so that only the parts you want to trust are actually trusted, the rest of the function is safe. It doesn't prevent you from having to locally verify that implementation leaks don't happen (for example, () trusted {free(ptr);}() can still leak dangling pointers out into the safe portion), but it allows you to focus where your code is trusted. For more details, see this: https://dlang.org/blog/2016/09/28/how-to-write-trusted-code-in-d/ -Steve
Dec 18 2018
On Tuesday, 18 December 2018 at 13:52:29 UTC, Steven Schveighoffer wrote:On 12/18/18 6:29 AM, Simen Kjærås wrote:I've been gathering assume related stuff like this in a lib under an "assume" template. You can generalize further with multiple attributes inside a non-eponymous thing and use them like: assume!fun.safe_(2); assume!fun.nogc_(2); I guess it's no very idiomatic D though, but I feel it reads better ... ok well maybe 🤷♂️: https://aliak00.github.io/bolts/bolts/assume/assume.html Easier to be more specific with searches for "assumeSafe" instead of just "assume!" though. Cheers, - AliOn Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote:Wow, I really like this. The only real problem is that one generally searches for trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with trusted (and specify the mangle). But any decent compiler should get rid of any overhead there. -SteveWhat's the preferred way of creating a temporary trusted scope without writing a separate function?Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { trusted auto unsafe(T...)(T args) { return fn(args); } } system void fun(int n) { writeln("foo!"); } safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); }
Dec 18 2018
On Tuesday, 18 December 2018 at 13:52:29 UTC, Steven Schveighoffer wrote:On 12/18/18 6:29 AM, Simen Kjærås wrote:While trusted wouldn't work, it could be named 'trusted' instead of 'unsafe'. That's not gonna help those who search for ' trusted', but it's closer, at least. -- Simensafe unittest { unsafe!({ fun(2); }); unsafe!fun(2); }Wow, I really like this. The only real problem is that one generally searches for trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref.
Dec 19 2018