August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Sunday, 25 August 2024 at 10:28:57 UTC, Manu wrote: > On Sun, 25 Aug 2024 at 19:26, Dom DiSc via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > >> On Saturday, 24 August 2024 at 17:10:39 UTC, Manu wrote: >> > We need to have: >> > >> > @trusted { >> > some_code; >> > } >> >> We have: >> >> () @trusted { >> some_code; >> }(); >> >> Which works kind of the same, beside it's ugly as hell. Until we have real trusted blocks, I use this (heavily). > > > > ..."kind of the same" [...] > I hope we can agree that this is definitely not 'kind of the same'... > > And that's to say nothing about the damage it causes to the debug info, and the ability to breakpoint and step through the code in a sane way. Completely unacceptable hack. I won't give this pattern the dignity of my fingertips approval under any circumstances. It should not be legitimised. Of course this should be better optimized, but I use this almost always only to call a @system function, which get less overhead (or maybe even DMD is able to recognize a single call in a call, and optimize it away). But I fully agree, this should be replaced by true trusted blocks, the sooner the better. |
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Sunday, 25 August 2024 at 10:32:31 UTC, Manu wrote:
> On Sun, 25 Aug 2024 at 19:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On Saturday, 24 August 2024 at 17:43:38 UTC, Manu wrote:
>> > On Sun, 25 Aug 2024 at 03:31, Richard (Rikki) Andrew Cattermole via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> >
>> >> On 25/08/2024 5:10 AM, Manu wrote:
>> >> > [...]
>> >>
>> >> I've been considering something along these lines.
>> >>
>> >> Specifically, ``@trusted`` does not mean the entire body shouldn't be verified. It just means that you are going to do something naughty that needs looking at.
>> >>
>> >> So you need annotated scopes inside of it, to do the naughty thing.
>>
>> Just wrote a trusted function and call it: that's the sane way to do it and respect code reviewer hard job.
>
>
> ...so, because I'm going to make one single unsafe function call inside of some function, I should eject all other related or unrelated safety checks for the entire surrounding context?
No, you should isolate the unsafe part of code into a function, explain why it’s unsafe, the intent of the code, the expected parameter values and the expected returns, so that reviewer can check that the interface is really memory safe.
Then call this extremely simple function from the rest of safe code safe code.
|
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson Attachments:
| On Sun, 25 Aug 2024 at 20:46, Nicholas Wilson via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> On Sunday, 25 August 2024 at 10:28:57 UTC, Manu wrote:
> > On Sun, 25 Aug 2024 at 19:26, Dom DiSc via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> >
> >> On Saturday, 24 August 2024 at 17:10:39 UTC, Manu wrote:
> > I hope we can agree that this is definitely not 'kind of the same'...
> >
> > And that's to say nothing about the damage it causes to the debug info, and the ability to breakpoint and step through the code in a sane way. Completely unacceptable hack. I won't give this pattern the dignity of my fingertips approval under any circumstances. It should not be legitimised.
>
> was that with DMD without optimisations, or LDC with
> optimisations?
> If this is the former, that's probably that's to be expected.
>
Of course it's expected; that's why I'm saying it's a completely insane
pattern.
Code quality without optimisations is extremely important, for the reasons
I said above; debugability, breakability, stepability.
If you abandon debug code quality, you end up with rust; completely
unworkable, with no tools except printf like it's 1980-something.
The amount of time you spend working on debug code vs release code is like 10,000:1. Optimisation quality is important obviously, but debug code quality should never be overlooked.
|
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi Attachments:
| On Sun, 25 Aug 2024 at 21:31, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> On Sunday, 25 August 2024 at 10:32:31 UTC, Manu wrote:
> > On Sun, 25 Aug 2024 at 19:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> >
> >> On Saturday, 24 August 2024 at 17:43:38 UTC, Manu wrote:
> >> > On Sun, 25 Aug 2024 at 03:31, Richard (Rikki) Andrew Cattermole via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >> >
> >> >> On 25/08/2024 5:10 AM, Manu wrote:
> >> >> > [...]
> >> >>
> >> >> I've been considering something along these lines.
> >> >>
> >> >> Specifically, ``@trusted`` does not mean the entire body shouldn't be verified. It just means that you are going to do something naughty that needs looking at.
> >> >>
> >> >> So you need annotated scopes inside of it, to do the naughty thing.
> >>
> >> Just wrote a trusted function and call it: that's the sane way to do it and respect code reviewer hard job.
> >
> >
> > ...so, because I'm going to make one single unsafe function call inside of some function, I should eject all other related or unrelated safety checks for the entire surrounding context?
>
> No, you should isolate the unsafe part of code into a function, explain why it’s unsafe, the intent of the code, the expected parameter values and the expected returns, so that reviewer can check that the interface is really memory safe.
>
> Then call this extremely simple function from the rest of safe code safe code.
>
>
So, this then:
extern(C) int myUnsafeFunction(int x, int y);
@trusted int myPointlessWrapper(int x, int y)
{
return myUnsafeFunction (x, y);
}
@safe mySuperSafeFunction(...)
{
//... lots of code
int r = myPointlessWrapper(arg1, arg2);
//... lots of code
}
Brilliant.
|
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Sunday, 25 August 2024 at 11:40:06 UTC, Manu wrote:
> On Sun, 25 Aug 2024 at 21:31, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On Sunday, 25 August 2024 at 10:32:31 UTC, Manu wrote:
>> > On Sun, 25 Aug 2024 at 19:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>> >
>> >> On Saturday, 24 August 2024 at 17:43:38 UTC, Manu wrote:
>> >> > On Sun, 25 Aug 2024 at 03:31, Richard (Rikki) Andrew Cattermole via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> >> >
>> >> >> On 25/08/2024 5:10 AM, Manu wrote:
>> >> >> > [...]
>> >> >>
>> >> >> I've been considering something along these lines.
>> >> >>
>> >> >> Specifically, ``@trusted`` does not mean the entire body shouldn't be verified. It just means that you are going to do something naughty that needs looking at.
>> >> >>
>> >> >> So you need annotated scopes inside of it, to do the naughty thing.
>> >>
>> >> Just wrote a trusted function and call it: that's the sane way to do it and respect code reviewer hard job.
>> >
>> >
>> > ...so, because I'm going to make one single unsafe function call inside of some function, I should eject all other related or unrelated safety checks for the entire surrounding context?
>>
>> No, you should isolate the unsafe part of code into a function, explain why it’s unsafe, the intent of the code, the expected parameter values and the expected returns, so that reviewer can check that the interface is really memory safe.
>>
>> Then call this extremely simple function from the rest of safe code safe code.
>>
>>
> So, this then:
>
> extern(C) int myUnsafeFunction(int x, int y);
>
> @trusted int myPointlessWrapper(int x, int y)
> {
> return myUnsafeFunction (x, y);
> }
>
> @safe mySuperSafeFunction(...)
> {
> //... lots of code
>
> int r = myPointlessWrapper(arg1, arg2);
>
> //... lots of code
> }
>
> Brilliant.
That’s sidestepping the problem from your side: there’s no explanation why myUnsafeFunction has an unsafe interface, under what condition it’s unsafe, and what it’s supposed to do. Neither any check that it’s parameters are valid and they are not turning into memory unsafety.
A reviewer for sure will ask you to add that information and assurance about memory safety of calling myUnsadeFunction
If the extern(C) function is intese memory safe, there should be a way to mark the declaration @safe, also with importC, and there we can reason about a solution.
|
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi Attachments:
| On Sun, 25 Aug 2024 at 21:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> On Sunday, 25 August 2024 at 11:40:06 UTC, Manu wrote:
> > On Sun, 25 Aug 2024 at 21:31, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> >
> >> On Sunday, 25 August 2024 at 10:32:31 UTC, Manu wrote:
> >> > On Sun, 25 Aug 2024 at 19:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> >> >
> >> >> On Saturday, 24 August 2024 at 17:43:38 UTC, Manu wrote:
> >> >> > On Sun, 25 Aug 2024 at 03:31, Richard (Rikki) Andrew
> >> >> > Cattermole via Digitalmars-d
> >> >> > <digitalmars-d@puremagic.com> wrote:
> >> >> >
> >> >> >> On 25/08/2024 5:10 AM, Manu wrote:
> >> >> >> > [...]
> >> >> >>
> >> >> >> I've been considering something along these lines.
> >> >> >>
> >> >> >> Specifically, ``@trusted`` does not mean the entire body
> >> >> >> shouldn't be verified. It just means that you are going
> >> >> >> to do something naughty that needs looking at.
> >> >> >>
> >> >> >> So you need annotated scopes inside of it, to do the naughty thing.
> >> >>
> >> >> Just wrote a trusted function and call it: that's the sane way to do it and respect code reviewer hard job.
> >> >
> >> >
> >> > ...so, because I'm going to make one single unsafe function call inside of some function, I should eject all other related or unrelated safety checks for the entire surrounding context?
> >>
> >> No, you should isolate the unsafe part of code into a
> >> function, explain why it’s unsafe, the intent of the code, the
> >> expected parameter values and the expected returns, so that
> >> reviewer can check that the interface is really memory safe.
> >>
> >> Then call this extremely simple function from the rest of safe code safe code.
> >>
> >>
> > So, this then:
> >
> > extern(C) int myUnsafeFunction(int x, int y);
> >
> > @trusted int myPointlessWrapper(int x, int y)
> > {
> > return myUnsafeFunction (x, y);
> > }
> >
> > @safe mySuperSafeFunction(...)
> > {
> > //... lots of code
> >
> > int r = myPointlessWrapper(arg1, arg2);
> >
> > //... lots of code
> > }
> >
> > Brilliant.
>
> That’s sidestepping the problem from your side: there’s no
> explanation why myUnsafeFunction has an unsafe interface, under
> what condition it’s unsafe, and what it’s supposed to do. Neither
> any check that it’s parameters are valid and they are not turning
> into memory unsafety.
>
> A reviewer for sure will ask you to add that information and assurance about memory safety of calling myUnsadeFunction
>
> If the extern(C) function is intese memory safe, there should be a way to mark the declaration @safe, also with importC, and there we can reason about a solution.
I think you might have missed the point here... we're talking about calling
C libraries.
It already has its interface nicely presented and documented, with expected
arguments and returns all written out.
We just want to call a function, that's all. There's no safety 'risk' here
to comment on, unless you consider using a C library to be a risk in
principle.
|
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Sunday, 25 August 2024 at 12:47:13 UTC, Manu wrote:
> On Sun, 25 Aug 2024 at 21:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On Sunday, 25 August 2024 at 11:40:06 UTC, Manu wrote:
>> > On Sun, 25 Aug 2024 at 21:31, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>> >
>> >> On Sunday, 25 August 2024 at 10:32:31 UTC, Manu wrote:
>> >> > On Sun, 25 Aug 2024 at 19:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>> >> >
>> >> >> On Saturday, 24 August 2024 at 17:43:38 UTC, Manu wrote:
>> >> >> > On Sun, 25 Aug 2024 at 03:31, Richard (Rikki) Andrew
>> >> >> > Cattermole via Digitalmars-d
>> >> >> > <digitalmars-d@puremagic.com> wrote:
>> >> >> >
>> >> >> >> On 25/08/2024 5:10 AM, Manu wrote:
>> >> >> >> > [...]
>> >> >> >>
>> >> >> >> I've been considering something along these lines.
>> >> >> >>
>> >> >> >> Specifically, ``@trusted`` does not mean the entire body
>> >> >> >> shouldn't be verified. It just means that you are going
>> >> >> >> to do something naughty that needs looking at.
>> >> >> >>
>> >> >> >> So you need annotated scopes inside of it, to do the naughty thing.
>> >> >>
>> >> >> Just wrote a trusted function and call it: that's the sane way to do it and respect code reviewer hard job.
>> >> >
>> >> >
>> >> > ...so, because I'm going to make one single unsafe function call inside of some function, I should eject all other related or unrelated safety checks for the entire surrounding context?
>> >>
>> >> No, you should isolate the unsafe part of code into a
>> >> function, explain why it’s unsafe, the intent of the code, the
>> >> expected parameter values and the expected returns, so that
>> >> reviewer can check that the interface is really memory safe.
>> >>
>> >> Then call this extremely simple function from the rest of safe code safe code.
>> >>
>> >>
>> > So, this then:
>> >
>> > extern(C) int myUnsafeFunction(int x, int y);
>> >
>> > @trusted int myPointlessWrapper(int x, int y)
>> > {
>> > return myUnsafeFunction (x, y);
>> > }
>> >
>> > @safe mySuperSafeFunction(...)
>> > {
>> > //... lots of code
>> >
>> > int r = myPointlessWrapper(arg1, arg2);
>> >
>> > //... lots of code
>> > }
>> >
>> > Brilliant.
>>
>> That’s sidestepping the problem from your side: there’s no
>> explanation why myUnsafeFunction has an unsafe interface, under
>> what condition it’s unsafe, and what it’s supposed to do. Neither
>> any check that it’s parameters are valid and they are not turning
>> into memory unsafety.
>>
>> A reviewer for sure will ask you to add that information and assurance about memory safety of calling myUnsadeFunction
>>
>> If the extern(C) function is intese memory safe, there should be a way to mark the declaration @safe, also with importC, and there we can reason about a solution.
>
>
> I think you might have missed the point here... we're talking about calling
> C libraries.
> It already has its interface nicely presented and documented, with expected
> arguments and returns all written out.
> We just want to call a function, that's all. There's no safety 'risk' here
> to comment on, unless you consider using a C library to be a risk in
> principle.
Using a C library IS a risk in principle, if it includes memory unsafe function interfaces.
The memory unsafe C interface (@system) must be called from a @trusted function that ensure that proper parameters and conditions are properly set to not trigger memory unsafely: that's basically the whole point of @trusted.
If you instead mean that SOME extern(C) function is non memory unsafe, and that have been discovered reading its documentation, you could declare the C declaration (in the D module) directly as @safe. That's what happened to be before importC.
I further agree with you that would be good to have a clever way to declare @safe declarations for SOME function automatically declared by importC.
BTW, nice to see you here again in the forum, Manu! :-P
Further, I agree
|
August 26 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paolo Invernizzi Attachments:
| On Sun, 25 Aug 2024 at 23:25, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Sunday, 25 August 2024 at 12:47:13 UTC, Manu wrote: > > On Sun, 25 Aug 2024 at 21:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > > > >> On Sunday, 25 August 2024 at 11:40:06 UTC, Manu wrote: > >> > On Sun, 25 Aug 2024 at 21:31, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > >> > > >> >> On Sunday, 25 August 2024 at 10:32:31 UTC, Manu wrote: > >> >> > On Sun, 25 Aug 2024 at 19:56, Paolo Invernizzi via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > >> >> > > >> >> >> On Saturday, 24 August 2024 at 17:43:38 UTC, Manu wrote: > >> >> >> > On Sun, 25 Aug 2024 at 03:31, Richard (Rikki) Andrew > >> >> >> > Cattermole via Digitalmars-d > >> >> >> > <digitalmars-d@puremagic.com> wrote: > >> >> >> > > >> >> >> >> On 25/08/2024 5:10 AM, Manu wrote: > >> >> >> >> > [...] > >> >> >> >> > >> >> >> >> I've been considering something along these lines. > >> >> >> >> > >> >> >> >> Specifically, ``@trusted`` does not mean the entire > >> >> >> >> body > >> >> >> >> shouldn't be verified. It just means that you are > >> >> >> >> going > >> >> >> >> to do something naughty that needs looking at. > >> >> >> >> > >> >> >> >> So you need annotated scopes inside of it, to do the naughty thing. > >> >> >> > >> >> >> Just wrote a trusted function and call it: that's the > >> >> >> sane way to do it and respect code reviewer hard job. > >> >> > > >> >> > > >> >> > ...so, because I'm going to make one single unsafe > >> >> > function call inside of some function, I should eject all > >> >> > other related or unrelated safety checks for the entire > >> >> > surrounding context? > >> >> > >> >> No, you should isolate the unsafe part of code into a > >> >> function, explain why it’s unsafe, the intent of the code, > >> >> the > >> >> expected parameter values and the expected returns, so that > >> >> reviewer can check that the interface is really memory safe. > >> >> > >> >> Then call this extremely simple function from the rest of safe code safe code. > >> >> > >> >> > >> > So, this then: > >> > > >> > extern(C) int myUnsafeFunction(int x, int y); > >> > > >> > @trusted int myPointlessWrapper(int x, int y) > >> > { > >> > return myUnsafeFunction (x, y); > >> > } > >> > > >> > @safe mySuperSafeFunction(...) > >> > { > >> > //... lots of code > >> > > >> > int r = myPointlessWrapper(arg1, arg2); > >> > > >> > //... lots of code > >> > } > >> > > >> > Brilliant. > >> > >> That’s sidestepping the problem from your side: there’s no > >> explanation why myUnsafeFunction has an unsafe interface, under > >> what condition it’s unsafe, and what it’s supposed to do. > >> Neither > >> any check that it’s parameters are valid and they are not > >> turning > >> into memory unsafety. > >> > >> A reviewer for sure will ask you to add that information and assurance about memory safety of calling myUnsadeFunction > >> > >> If the extern(C) function is intese memory safe, there should be a way to mark the declaration @safe, also with importC, and there we can reason about a solution. > > > > > > I think you might have missed the point here... we're talking > > about calling > > C libraries. > > It already has its interface nicely presented and documented, > > with expected > > arguments and returns all written out. > > We just want to call a function, that's all. There's no safety > > 'risk' here > > to comment on, unless you consider using a C library to be a > > risk in > > principle. > > Using a C library IS a risk in principle, if it includes memory > unsafe function interfaces. > The memory unsafe C interface (@system) must be called from a > @trusted function that ensure that proper parameters and > conditions are properly set to not trigger memory unsafely: > that's basically the whole point of @trusted. > Right, but in ~95% of cases C functions don't have anything about them that makes them memory unsafe, or any relevant validation or concerning API material... they're just de-facto unsafe. Here's some great functions that I plucked from top of my head: float abs(float); int rand(); void sleep(int); int fclose(FILE); pid_t getpid(); It's obviously stupid to write a wrapper function for every single C function we use. That's entirely self-defeating. Why would anybody import a C header file if they have to write as many function wrappers as C function prototypes imported? Might as well have just written the prototypes... it's actually LESS code. And then there's maybe kinda contentious ones, like: FILE fopen(char* filename, char* mode); Now, clearly there's a null-termination concern here, but that's not actually a category of issue that @safe is concerned with as far as I know. Generally, the user just wants to do this: unsafe { FILE f = fopen(filename.toStringz, "rb"); } There's no value in writing a whole function wrapper to automate a call to toStringz(). I'm not even sure that call is actually unsafe anyway. toStringz() isn't unsafe...? I further agree with you that would be good to have a clever way > to declare @safe declarations for SOME function automatically declared by importC. > That list I wrote above and a million functions of that nature; they don't have any interaction with @safe... declaring them @system is nothing more than a nuisance. Nothing is added by not trusting them. If there's some API tell-tales that can definitively determine the safety of a function, then maybe it could make an educated guess... but failing that, then there's a serious practical conundrum here. BTW, nice to see you here again in the forum, Manu! :-P > 🎉 🎉 🎉 |
August 25 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dom DiSc | On 8/25/24 13:06, Dom DiSc wrote:
>
> But I fully agree, this should be replaced by true trusted blocks, the sooner the better.
You cannot have a "trusted block". It just does not work. The interface to any trusted thing has to be clearly delineated.
|
August 26 Re: ImportC and nothrow/@nogc? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr Attachments:
| On Mon, 26 Aug 2024, 07:56 Timon Gehr via Digitalmars-d, < digitalmars-d@puremagic.com> wrote: > On 8/25/24 13:06, Dom DiSc wrote: > > > > But I fully agree, this should be replaced by true trusted blocks, the sooner the better. > > You cannot have a "trusted block". It just does not work. The interface to any trusted thing has to be clearly delineated. > Well it obviously does work in some sense, because it's the de facto standard that people generally expect in numerous languages. People are going to have it one way or another; whether it's a ridiculous hack like `()@trusted { ... }();` or otherwise. It's what other languages with this sort of thing do. We don't have a better offering to motivate people to deviate from their patterns. Resisting that degrades D. > |
Copyright © 1999-2021 by the D Language Foundation