August 25
On 8/24/2024 10:15 AM, Manu wrote:
> *sigh* ... I'm not going to do that.
> ImportC either works, or it doesn't... and it currently doesn't work, and I'm just going to move on.
> By far the easiest and least ridiculous feeling thing can do right now is to just prototype the occasional C library call inline immediately before the call, which is what I've moved on with.
> Fortunately my call volume is low.

You're right, that will work.

I tried to make C calls default to @trusted. Every single person in the community who voiced an opinion on it was dead set against it. But here you are, saying who cares what C does.

I've got a cannon on one side aimed at me, and a flak gun on the other side.

What do you suggest I do?

August 25
On 8/23/2024 11:23 PM, Dukc wrote:
> OTOH a C function `longjmp`ing is like a D function throwing unrecoverable errors. It's still `nothrow`, it's just that `setjmp`ing (like catching unrecoverables) is unsafe, since it can break the D type system by skipping destructors and `finally` blocks.

The fact that C++ compilers that translate C++ to C code use setjmp/longjmp to implement EH is sufficient to explain that. If that's not enough, take a look at how it is implemented. It uses the same EH scheme as C++ does.
August 25
On 8/24/2024 10:29 AM, Richard (Rikki) Andrew Cattermole wrote:
> So you need annotated scopes inside of it, to do the naughty thing.

We did that with @trusted lambdas.

The result was @safe turned into a joke.

August 26
On 26/08/2024 5:42 PM, Walter Bright wrote:
> On 8/24/2024 10:29 AM, Richard (Rikki) Andrew Cattermole wrote:
>> So you need annotated scopes inside of it, to do the naughty thing.
> 
> We did that with @trusted lambdas.
> 
> The result was @safe turned into a joke.

That doesn't sound like what I was suggesting there.

To clarify:

```d
void func() @trusted {
	@trusted {
		unsafe_thing;
	}

	safe_only_thing;
	unsafe_thing; // Error
}
```

Not:

```d
void func() @safe {
	@trusted {
		unsafe_thing;
	}
}
```
August 25
@trusted means the function has an @safe interface. What the function does internally is not checked. For example:

```
@trusted int[] foo()
{
    int* p = cast(int*)malloc(10 * int.sizeof);
    assert(p);
    int[] a = p[0 .. 10];
    return a;
}
```
has a memory safe interface. The following:

```
@trusted int[] foo()
{
    int* p = cast(int*)malloc(10 * int.sizeof);
    assert(p);
    int[] a = p[0 .. 11]; // not memory safe
    return a;
}
```
does not.
August 25
On 8/25/2024 3:43 AM, Nicholas Wilson wrote:
> was that with DMD without optimisations, or LDC with optimisations?
> If this is the former, that's probably that's to be expected.

Kinda unfair to run dmd without optimizations and compare with ldc with? Here's dmd with -O -inline:

```
_D5test211stupid_hackFiiZi:
0000:   48 83 EC 18              sub       RSP,018h
0004:   89 7C 24 08              mov       8[RSP],EDI
0008:   89 74 24 10              mov       010h[RSP],ESI
000c:   C7 04 24 00 00 00 00     mov       [RSP],0
0013:   03 74 24 08              add       ESI,8[RSP]
0017:   89 34 24                 mov       [RSP],ESI
001a:   89 F0                    mov       EAX,ESI
001c:   48 83 C4 18              add       RSP,018h
0020:   C3                       ret
```
August 26
Mixing safe and trusted blocks into the same function just doesn't work. Timon pointed out why in another post in this thread.

I take that back. It appears to work, but it does not, as trusted code needs to provide a safe interface to it. That doesn't happen if it's just a "suppress the error message" hack.
August 26
On 26/08/2024 7:25 PM, Walter Bright wrote:
> Mixing safe and trusted blocks into the same function just doesn't work. Timon pointed out why in another post in this thread.
> 
> I take that back. It appears to work, but it does not, as trusted code needs to provide a safe interface to it. That doesn't happen if it's just a "suppress the error message" hack.

I agree there is a certain amount of uneasiness of logic that would be doable with it.

Not worth an ideas forum post, without this figured out and if it was part of a bigger design.

The problem is though, there shouldn't be a fundamental difference between a function body, and a scope within a function body.

So I'll agree that it appears to work, but there is likely holes in it.
August 26
On Sunday, 25 August 2024 at 16:58:53 UTC, Manu wrote:
> 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:
>> >> > [...]
>> >>
>> >> 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.

If you know that 100% of the C function prototypes you are importing are memory safe, then yes, that's yes, having them imported as @system is an annoyance, and DLang can be improved with some way to pragma the compiler to importC the file as @safe

On the other side, if you know that you have 95% of memory safety C functions, and 5% of memory unsafe function, marking that 5% as @trusted or @safe is just safe-washing, it's not acceptable in a code base that aims to be serious about memory safety.

> 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...?

Indeed we do that all the time, to provide some kind of D-way to call C-API. As you see, the inconvenience mark it's just a matter of taste, an opinion.

> 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.

The point here is that's not something like 'maybe my process is memory safe, by educated guess', it's not a matter of being practical or not. If memory safeties is a value, than it should be threaded seriously also if it involves not practical way of ensuring it.

Any addition to alleviate the burden is welcomed, especially for import C, but without throwing the @safety baby with the water.


August 26
Manu kirjoitti 25.8.2024 klo 19.58:
> 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...?

Well, `toStringz` copies the string to append a zero. Besides, `fopen` takes char pointers, not arrays, unlike `toStringz`. So this would compile: `fopen(new char('u'), new char('b'))` .