June 03
On Saturday, 1 June 2024 at 21:06:05 UTC, Timon Gehr wrote:
> On 5/30/24 20:35, Atila Neves wrote:
>> https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md
>> 
>> Destroy!
>
> - I think even more important than the default is the ability to change the default (e.g. `default(@safe):`). This does not exist currently, but it would be required for easy migration.

That's a good point, but: do we only do it for this attribute or for the others as well?

> - There is not really any value in being able to write `@safe extern(C)/extern(C++)` prototypes. It's wrong and any linter would need to have a warning for it. I would just require an explicit `@system` or `@trusted` annotation. Note that for `extern(C)/extern(C++)` prototypes, `@safe` and `@trusted` have _the same semantics and interpretation_, but only one of them looks adequately dangerous and is easy to grep.

I get this, but the issue is that those functions might actually be written in D.

> - The DIP should clarify whether annotations like `@safe:` apply to prototypes or whether prototypes always need an individual annotation.

Added.


June 03

On Monday, 3 June 2024 at 11:08:36 UTC, Quirin Schroll wrote:

>

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

[...]

Because of a lack of mangling, extern(X) where X isn’t D shouldn’t ever be allowed to be annotated @safe unless it’s a definition.

[...]

I could see changing it to this; but what if it's writen in D and someone wants to use a .di file?

June 04

On Monday, 3 June 2024 at 15:56:05 UTC, Atila Neves wrote:

>

On Monday, 3 June 2024 at 11:08:36 UTC, Quirin Schroll wrote:

>

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

[...]

Because of a lack of mangling, extern(X) where X isn’t D shouldn’t ever be allowed to be annotated @safe unless it’s a definition.

[...]

I could see changing it to this; but what if it's writen in D and someone wants to use a .di file?

TBH, I don’t know what .di files really are. AFAIK, they’re basically what a header file in C/C++ is. They contain declarations. The biggest difference to C/C++ is that .di files are compiler generated and a programmer might occasionally read them, but essentially never write or edit one. Correct me if I’m wrong.

For extern(C/C++) functions implemented in D, whether the .di file contains contains @safe or @trusted declarations doesn’t really make a difference. For callers, they’re the same. They also mangle the same. There may be a difference what reflection sees, though.

I notice one issue, that @trusted is not the same as @safe from the caller perspective. In extern(D), they also mangle differently, which is fine but weird.

I noticed that this does not compile:

extern(C) void f() @trusted;
extern(C) void f() @safe { }
void main() { f(); } // error: `f` ambiguous

This could be an issue for the D module that defines the function, maybe it isn’t. If it is, I guess that could be changed, i.e. for extern(C/C++) make the compiler realize that function declarations only differing in attributes refer to the same function. I cannot imagine someone relies on this being an error.

June 05
On 05/06/2024 12:13 AM, Quirin Schroll wrote:
> On Monday, 3 June 2024 at 15:56:05 UTC, Atila Neves wrote:
>> On Monday, 3 June 2024 at 11:08:36 UTC, Quirin Schroll wrote:
>>> On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:
>>>> [...]
>>>
>>> Because of a lack of mangling, `extern(X)` where `X` isn’t `D` shouldn’t ever be allowed to be annotated `@safe` unless it’s a definition.
>>>
>>> [...]
>>
>> I could see changing it to this; but what if it's writen in D and someone wants to use a .di file?
> 
> TBH, I don’t know what .di files really are. AFAIK, they’re basically what a header file in C/C++ is. They contain declarations. The biggest difference to C/C++ is that .di files are compiler generated and a programmer might occasionally read them, but essentially never write or edit one. Correct me if I’m wrong.

.di files are currently all hand written.

The only thing special about them is the convention that they should have methods discarded and that they get priority over .d files. In all other ways the are the same as .d files.

The .di generator currently runs _before_ semantic, this means no inferred attributes get emitted. If you move it to after semantic (assuming no other issues lol) scope and return will be emitted in the wrong order messing up mangling.

Basically right now the .di generator can't be used. I am working on fixing most of the blocking issues, but unfortunately I am going to hand it off due to some semantic rewrites that I cannot fix.

A quick look on ABI page, both ``@safe`` and ``@trusted`` get name mangled differently.

https://dlang.org/spec/abi.html#FuncAttrTrusted

So yes we'd have to allow ``@safe`` on function declarations without bodies unfortunately.
June 06
On 6/3/24 17:55, Atila Neves wrote:
>> - There is not really any value in being able to write `@safe extern(C)/extern(C++)` prototypes. It's wrong and any linter would need to have a warning for it. I would just require an explicit `@system` or `@trusted` annotation. Note that for `extern(C)/extern(C++)` prototypes, `@safe` and `@trusted` have _the same semantics and interpretation_, but only one of them looks adequately dangerous and is easy to grep.
> 
> I get this, but the issue is that those functions might actually be written in D.

Why is this an issue?
June 06

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

I think it should eventually happen, but we are not ready for it.
The real problem is that it is currently hard to compose with attributes. The problem is most evident with @safe, but happens with nothrow, pure, etc...
Until we solve this problem, @safe-by-default would just be trading one pain for another, and breaking the ecosystem in the process. We saw what happened with DIP1000...

Provided the issue with composition of attribute is fixed, I would make a suggestion to the DIP: Remove @safe entirely. Others have hinted at it, and it seems the solution is simple: Un-annotated definitions are @safe, definitions can be annotated to be @system or @trusted, and extern definitions MUST be annotated. It is also changing the perception - @safe is not an add-on anymore.

June 07
On Thursday, 6 June 2024 at 17:01:05 UTC, Timon Gehr wrote:
> On 6/3/24 17:55, Atila Neves wrote:
>>> - There is not really any value in being able to write `@safe extern(C)/extern(C++)` prototypes. It's wrong and any linter would need to have a warning for it. I would just require an explicit `@system` or `@trusted` annotation. Note that for `extern(C)/extern(C++)` prototypes, `@safe` and `@trusted` have _the same semantics and interpretation_, but only one of them looks adequately dangerous and is easy to grep.
>> 
>> I get this, but the issue is that those functions might actually be written in D.
>
> Why is this an issue?

The compiler would have access to the body and so would verify its @safe-ness.
June 07
On 6/7/24 02:58, Atila Neves wrote:
> On Thursday, 6 June 2024 at 17:01:05 UTC, Timon Gehr wrote:
>> On 6/3/24 17:55, Atila Neves wrote:
>>>> - There is not really any value in being able to write `@safe extern(C)/extern(C++)` prototypes. It's wrong and any linter would need to have a warning for it. I would just require an explicit `@system` or `@trusted` annotation. Note that for `extern(C)/extern(C++)` prototypes, `@safe` and `@trusted` have _the same semantics and interpretation_, but only one of them looks adequately dangerous and is easy to grep.
>>>
>>> I get this, but the issue is that those functions might actually be written in D.
>>
>> Why is this an issue?
> 
> The compiler would have access to the body and so would verify its @safe-ness.

A function prototype does not have a body and the actual body may be in another compilation unit. For `extern(D)` the mangled name gives some assurances, but not for `extern(C)` and `extern(C++)`.

I guess maybe an additional alternative name can be given to `@safe` `extern(C)` functions, but I doubt that linker errors are a great UX for safety checks.
June 07
Timon Gehr kirjoitti 7.6.2024 klo 17.25:
> On 6/7/24 02:58, Atila Neves wrote:
>> On Thursday, 6 June 2024 at 17:01:05 UTC, Timon Gehr wrote:
>>> On 6/3/24 17:55, Atila Neves wrote:
>>>>> - There is not really any value in being able to write `@safe extern(C)/extern(C++)` prototypes. It's wrong and any linter would need to have a warning for it. I would just require an explicit `@system` or `@trusted` annotation. Note that for `extern(C)/extern(C++)` prototypes, `@safe` and `@trusted` have _the same semantics and interpretation_, but only one of them looks adequately dangerous and is easy to grep.
>>>>
>>>> I get this, but the issue is that those functions might actually be written in D.
>>>
>>> Why is this an issue?
>>
>> The compiler would have access to the body and so would verify its @safe-ness.
> 
> A function prototype does not have a body and the actual body may be in another compilation unit. For `extern(D)` the mangled name gives some assurances, but not for `extern(C)` and `extern(C++)`.
> 
> I guess maybe an additional alternative name can be given to `@safe` `extern(C)` functions, but I doubt that linker errors are a great UX for safety checks.

When Átila wrote his last reply I was still agreeing with him. Why? I missed that you, in your earlier post, wrote specifically about function prototypes, not any C/C++ linked functions. I guess Átila did too - I can't see why else he would have thought the compiler has access to the function body.

If I'm assessing this right, you're actually in agreement with each other. The only disagreement you maybe have is whether it's this DIP or some later alternative that should change the rules for those functions.
June 10

On Tuesday, 4 June 2024 at 20:33:07 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

On 05/06/2024 12:13 AM, Quirin Schroll wrote:

>

On Monday, 3 June 2024 at 15:56:05 UTC, Atila Neves wrote:

>

On Monday, 3 June 2024 at 11:08:36 UTC, Quirin Schroll wrote:

>

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

[...]

Because of a lack of mangling, extern(X) where X isn’t D shouldn’t ever be allowed to be annotated @safe unless it’s a definition.

[...]

I could see changing it to this; but what if it's writen in D and someone wants to use a .di file?

TBH, I don’t know what .di files really are. AFAIK, they’re basically what a header file in C/C++ is. They contain declarations. The biggest difference to C/C++ is that .di files are compiler generated and a programmer might occasionally read them, but essentially never write or edit one. Correct me if I’m wrong.

.di files are currently all hand written.

[…]

A quick look on ABI page, both @safe and @trusted get name mangled differently.

https://dlang.org/spec/abi.html#FuncAttrTrusted

So yes we'd have to allow @safe on function declarations without bodies unfortunately.

I’m not referring to extern(D) functions. I knew those have attributes mangled into them, so you’ll get linker errors on an attribute mismatch between a function’s prototype and its definition. The issue is, for extern(C/C++) functions, attributes aren’t mangled into it, so the linker is blind to the mismatch.

Of course, linker errors aren’t great, but still a lot better than UB at runtime.

If .di files are hand-written, we must absolutely not allow @safe annotations on extern(C/C++) function declarations. Those must all be @trusted, even if the validation by the programmer only requires grepping the function name and observing that the function definition (the implementation) is annotated @safe, so the actual, difficult validation is done by the compiler. However, @trusted is warranted, as when the implementation isn’t annotated @safe (either because it’s not annotated or is in another language entirely), it simply may not be safe, and therefore, a @safe function declaration in a .di file would be a lie, and the bad thing about that is that it’s not going to be caught by the compiler or linker.

The @trusted attribute only means that some programmer-side verification established the function is actually safe. It does not mean the verification can’t be as simple as a grep.

In fact, if .di files are hand written, changing @safe to @trusted after copying a function signature isn’t too wild to ask. The simple fact is, on non-D functions, @safe can’t be verified except on function definitions, and therefore can’t be used. @Átila: Making exceptions to @safe so that it isn’t fool-proof would be a disaster to D’s marketability.