April 08, 2020
On 08.04.20 21:19, Steven Schveighoffer wrote:
> 
> ---
> module a;
> extern(C) void perfectly_safe @safe {
>   // ...
> }
> ---
> ---
> module b;
> extern(C) void perfectly_safe() @safe;
> ---


---
module a;
extern(C) size_t perfectly_safe @safe {
 // ...
}
---
---
module b;
extern(C) int* perfectly_safe() @safe;
---
April 08, 2020
On 4/8/20 3:32 PM, Timon Gehr wrote:
> ---
> module a;
> extern(C) size_t perfectly_safe @safe {
>   // ...
> }
> ---
> ---
> module b;
> extern(C) int* perfectly_safe() @safe;
> ---

---
module a;
extern(C) size_t perfectly_safe @safe {
 // ...
}
---
---
module b;
extern(C) int* perfectly_safe() @trusted;
---

No difference. Same result.

-Steve
April 08, 2020
On 08.04.20 21:37, Steven Schveighoffer wrote:
> On 4/8/20 3:32 PM, Timon Gehr wrote:
>> ---
>> module a;
>> extern(C) size_t perfectly_safe @safe {
>>   // ...
>> }
>> ---
>> ---
>> module b;
>> extern(C) int* perfectly_safe() @safe;
>> ---
> 
> ---
> module a;
> extern(C) size_t perfectly_safe @safe {
>   // ...
> }
> ---
> ---
> module b;
> extern(C) int* perfectly_safe() @trusted;
> ---
> 
> No difference. Same result.
> 
> -Steve

This is a waste of time.
April 08, 2020
On 4/8/20 3:44 PM, Timon Gehr wrote:
> On 08.04.20 21:37, Steven Schveighoffer wrote:
>> No difference. Same result.
>>
> 
> This is a waste of time.

That is something we can agree on.

-Steve
April 08, 2020
On 08.04.20 21:53, Steven Schveighoffer wrote:
> On 4/8/20 3:44 PM, Timon Gehr wrote:
>> On 08.04.20 21:37, Steven Schveighoffer wrote:
>>> No difference. Same result.
>>>
>>
>> This is a waste of time.
> 
> That is something we can agree on.
> 
> -Steve

I'll explain why I think it's the case: If your opinion is truly that the following two code snippets are equivalent, we have reached an irreducible position:

---
void corrupt_memory()@trusted{ ... }

void main()@safe{
    corrupt_memory();
}
---
---
void corrupt_memory()@system{ ... }

void main()@system{
    corrupt_memory();
}
---

Anyone who thinks those two code snippets are essentially the same can safely ignore my line of argumentation, but everyone else should dismiss yours.
April 08, 2020
On 4/8/20 4:04 PM, Timon Gehr wrote:
> 
> I'll explain why I think it's the case: If your opinion is truly that the following two code snippets are equivalent, we have reached an irreducible position:
> 
> ---
> void corrupt_memory()@trusted{ ... }
> 
> void main()@safe{
>      corrupt_memory();
> }
> ---
> ---
> void corrupt_memory()@system{ ... }
> 
> void main()@system{
>      corrupt_memory();
> }
> ---
> 
> Anyone who thinks those two code snippets are essentially the same can safely ignore my line of argumentation, but everyone else should dismiss yours.

Strawman.

I never said that @trusted is the same as @system. I said that a @system function which has a @safe prototype is identical to a @system function that has a @trusted prototype. In both cases, the compiler accepts the function as callable from @safe code, does no checking, and never alerts the user.

The only reasonable case where extern(C) code that is actually @system should be prototyped @trusted is when the code isn't written in D. In that case, it's not possible to mark it @trusted, but one can reasonably assume that the code is technically @safe. For instance libc's cos() or something similar.

extern(C) code that is not checked @safe SHOULD NEVER be prototyped @safe. But it makes no sense to prevent extern(C) code that is @safe from being prototyped as @safe. Requiring one to write @trusted doesn't change anything as the code is still callable via @safe code, and just creates unnecessary annoyances.

We should not prevent accurate prototypes just because it's possible to write them incorrectly. Especially when the prevention doesn't disallow the exact same inaccurate prototypes written with @trusted vs. @safe.

If requiring @trusted prototypes for @safe functions gained any measurable quantity of safety, it would be worth it. It doesn't, so it's not.

-Steve
April 08, 2020
On Wednesday, 8 April 2020 at 20:47:40 UTC, Steven Schveighoffer wrote:
>
> The only reasonable case where extern(C) code that is actually @system should be prototyped @trusted is when the code isn't written in D. In that case, it's not possible to mark it @trusted, but one can reasonably assume that the code is technically @safe. For instance libc's cos() or something similar.
>
> extern(C) code that is not checked @safe SHOULD NEVER be prototyped @safe. But it makes no sense to prevent extern(C) code that is @safe from being prototyped as @safe. Requiring one to write @trusted doesn't change anything as the code is still callable via @safe code, and just creates unnecessary annoyances.

Just to make a counter argument against extern(C) being @system by default which is perhaps a bit counter intuitive. The programmer wants get things done fast and in practice the programmer doesn't care about if the FFI functions are @safe or @system. The programmer just want to call the FFI function the @safe function just as usual. In practice a programmer will almost every time put @safe or @trusted for every function that are imported.

Semantically having extern(C) @system makes sense but from a language usability point of view, every programmer will want to convert these in order to call the directly from @safe code without any wrapper. Programmers don't care (like a honey badger), they just want to call their code.

April 08, 2020
On Wed, Apr 08, 2020 at 09:14:14PM +0000, IGotD- via Digitalmars-d wrote: [...]
> Just to make a counter argument against extern(C) being @system by default which is perhaps a bit counter intuitive. The programmer wants get things done fast and in practice the programmer doesn't care about if the FFI functions are @safe or @system. The programmer just want to call the FFI function the @safe function just as usual. In practice a programmer will almost every time put @safe or @trusted for every function that are imported.

This argument does not make sense.  The whole point of @safe is to provide mechanically-checked guarantees that it does not do anything that might corrupt memory.  If it calls a function that is not @safe, that means the program as a whole does not live up to the promises of @safe, and therefore should be marked @system.  It does not make sense to hack it so that you can label a program @safe even though it calls something that ought to be @system.

If you need to call an FFI function (or whatever other function) and just want to get the job done, and you don't really care about how @safe works, then just write @system: at the top of your program and call it a day. Job done, we can all go home.


> Semantically having extern(C) @system makes sense but from a language usability point of view, every programmer will want to convert these in order to call the directly from @safe code without any wrapper. Programmers don't care (like a honey badger), they just want to call their code.

If they don't care, then their code is @system.  End of story.  I don't understand why someone would want to jump through hoops to call their code @safe when it actually isn't.


T

-- 
It only takes one twig to burn down a forest.
April 09, 2020
On 08.04.20 22:47, Steven Schveighoffer wrote:
> On 4/8/20 4:04 PM, Timon Gehr wrote:
>>
>> I'll explain why I think it's the case: If your opinion is truly that the following two code snippets are equivalent, we have reached an irreducible position:
>>
>> ---
>> void corrupt_memory()@trusted{ ... }
>>
>> void main()@safe{
>>      corrupt_memory();
>> }
>> ---
>> ---
>> void corrupt_memory()@system{ ... }
>>
>> void main()@system{
>>      corrupt_memory();
>> }
>> ---
>>
>> Anyone who thinks those two code snippets are essentially the same can safely ignore my line of argumentation, but everyone else should dismiss yours.
> 
> Strawman.
> ...

Right back at you.

> I never said that @trusted is the same as @system.

Nor did I claim you did. The snippets above differ only in who is to blame for the memory corruption. You claimed that's a non-essential detail, and that is not true, but I don't know how to make that point to you.
April 09, 2020
On 4/9/20 12:31 AM, Timon Gehr wrote:
> On 08.04.20 22:47, Steven Schveighoffer wrote:
>> I never said that @trusted is the same as @system.
> 
> Nor did I claim you did.

You just said:

"If your opinion is truly that the following two code snippets are equivalent"

and then presented two code snippets that showed the same function with implementation tagged as @system or @trusted. I don't know how I'm supposed to interpret your claim other than you think I believe they are equivalent.

> The snippets above differ only in who is to blame for the memory corruption. You claimed that's a non-essential detail, and that is not true, but I don't know how to make that point to you.

The snippets are different than what we are debating. We were not talking about trusted code being called from safe code, rather system code being incorrectly prototyped as @safe or @trusted. Whether you mark it incorrectly @safe or incorrectly @trusted is non-essential.

In both cases, the person who wrote the prototype is to blame, as the person who wrote the original code clearly meant it to be system, and the person who wrote the prototype got it wrong.

We have 3 situations:

1. The code is written as extern(C) in D, in which case, the exact safety attribute should be repeated as the prototype.
2. The code is written in some other language, but is @safe based on an examination either by spec or by actually proofreading the code. In which case, the prototype could be @trusted.
3. The code is written in some other language, and does not follow safety rules of D (e.g. memcpy). It should be marked @system.

In no circumstances should extern(C) code that is written outside D should be marked @safe. I would also consider it an error to write a prototype for an extern(C) D function other than what it actually is (@safe, @trusted, @system).

I consider both of those an error on the prototype author.

I would consider it a mistake to make it impossible to forward the exact attribute of a @safe extern(C) D function to the prototype.

-Steve