May 27, 2020
On Wednesday, 27 May 2020 at 09:50:50 UTC, Walter Bright wrote:
> Un-annotated C declarations should be a red flag to any competent QA team. Recognizing a false @trusted is a whole lot harder.

Is the actual problem those `@trusted:` declarations at the top of C headers?

There could be a simple solution to that:

Ban `@trusted:` and `@trusted { }` which apply to multiple symbols. Only allow `@trusted` to apply to a single symbol. For example:

---
@trusted:

extern(C) void memcpy (void*, void*, size_t);
extern(C) void write42 (void*);
---

Error.

---
@trusted extern(C) void memcpy (void*, void*, size_t);
@trusted extern(C) void write42 (void*);
---

OK, compiles. The bindings author has clearly added @trusted manually to each symbol.

Obviously there are escape hatches like mixins, code generation, etc.
May 27, 2020
On Wednesday, 27 May 2020 at 10:07:48 UTC, Johannes Loher wrote:
> Am 27.05.20 um 11:50 schrieb Walter Bright:
>> [...]
>> 
>> Un-annotated C declarations should be a red flag to any competent QA team. Recognizing a false @trusted is a whole lot harder.
>
> [...]
>
> Also in my opinion, a competent QA department should carefully look at any @trusted code /declarations. Maybe it is not a "red flag" but it is definitely something that needs to be checked with extra care.

I think additionally we shouldn't make D code review harder to do than it needs to be.

For a reviewer "something correct which is missing" is harder to pick up than "something wrong which is there" (@trusted/@system attributes)

When I, as an incompetent but trying QA department, come across a code change introducing a new module wrapping a C library and all tests pass, I would most likely not notice that the author did not type `@system:`. If there was an `@trusted:` at the top of the file it would be picked up by D-Scanner and help in code review. And well if someone slapped `@safe:` at the top of the file... read on:

Someone in this thread wrote something like "@safe" should be forbidden on functions without method body and instead only use @trusted or @system. I think it might even be you who brought it up? I love the idea of forbidding @safe when the compiler can't actually check the content of a function. @safe, @trusted and @system could then have perfect definitions without edge cases. And you would change the mangling of @safe and @trusted to be the same which was also brought up in this thread.
May 27, 2020
On Wednesday, 27 May 2020 at 13:42:08 UTC, Andrej Mitrovic wrote:
> Is the actual problem those `@trusted:` declarations at the top of C headers?
>
> There could be a simple solution to that:
>
> Ban `@trusted:` and `@trusted { }` which apply to multiple symbols. Only allow `@trusted` to apply to a single symbol. For

IMO, it makes things worse. Because the careless programmer will slap @trusted to every declaration (maybe with a script or find/replace macro of his editor). So now, we don't know if the annotation is greenwashing or careful examination of the definition.

At least with "@trusted:" and "@trusted { }", the greenwashing is obvious.
May 27, 2020
On Wednesday, 27 May 2020 at 10:46:11 UTC, Walter Bright wrote:
> On 5/27/2020 2:34 AM, Bastiaan Veelo wrote:
>> On Wednesday, 27 May 2020 at 09:09:58 UTC, Walter Bright wrote:
>>> On 5/26/2020 11:20 PM, Bruce Carneal wrote:
>>>> I'm not at all concerned with legacy non-compiling code of this nature.
>>>
>>> Apparently you agree it is not an actual problem.
>> 
>> Really? I don't know if you really missed the point being made, or you're being provocative. Both seem unlikely to me.
>
> His argument was:
>
> "Currently a machine checked @safe function calling an unannotated extern C routine will error out during compilation. This is great as the C routine was not machine checked, and generally can not be checked.  Post 1028, IIUC, the compilation will go through without complaint.  This seems quite clear.  What am I missing?"
>
> I replied that it was unlikely that such legacy code existed.
>
> He replied that he was not concerned about it.
>
> I.e. working legacy code is not going break.

You continue to miss the point.

Additionally, there never was any "working legacy code".  As established, the pre 1080 compiler would have rejected the code.  Does-not-compile != working-code.


May 27, 2020
On Wednesday, 27 May 2020 at 13:50:25 UTC, Bruce Carneal wrote:
> On Wednesday, 27 May 2020 at 10:46:11 UTC, Walter Bright wrote:
>> [...]
>
> You continue to miss the point.
>
> Additionally, there never was any "working legacy code".  As established, the pre 1080 compiler would have rejected the code.  Does-not-compile != working-code.

pre 1028 compiler
May 27, 2020
On Friday, 22 May 2020 at 01:22:19 UTC, Walter Bright wrote:
> I have made these points before, but I'll summarize them here
> for convenient referral.
>
 [big snip of very long and arguably tangential Java screw-up and other]

> How does this relate to safe by default?
>
> Consider the common (because that's how D started out) case of:
>
> ----- clibrary.d --------
>
>     T massage_data(... many parameters ...);
>     ... 200 more such declarations ...
>
> ----- app.d ----------
>
>     import clibrary;
>
>     void useClibrary( ... parameters ...) {
>         massage_data(parameters);
>     }
>
> ---------------------
>
> This code, today, does not use annotations and it works. It's been working
> for a long time. Now, we implement the amendment, and it stops compiling
> because useClibrary is @safe and massage_data is @system. The user is faced
> with the following alternatives:
>
> 1. Go through 200 functions in clibrary.d and determine which are @safe
> and which are @system. This is what we want them to do. We try to motivate
> this with compiler error messages. Unfortunately, this is both tedious and
> thoroughly impractical, as our poor user Will Not Know which are safe and
> which are system. We can correctly annotate core.stdc.stdio because I know
> those functions intimately. This is not true for other system C APIs, and
> even less true for some third party C library we're trying to interface to.

So, to condense and hopefully clarify: we can not use option 1) and @system by default because "our poor user Will Not Know which are safe and which are system"?
IOW, because someone unable to comment on safety would be inconvenienced we enable them to inject more code into the ecosphere by making @safe the default.

What am I missing?

>
> 2. Annotate useClibrary() as @trusted or @system. While easier, this causes
> all benefits to @safe by default to be lost.
>
> 3. Wrap the call to massage_data() with:
>
>     () @trusted { massage_data(parameters); } ();
>
> If there are a lot of calls to clibrary, this is going to look pretty awful.
> Nobody likes writing or reading such ugly code. It's ok here and there, but
> not as a general thing.
>
> 4. Edit clibrary.d and make the first line:
>
>     @safe:
>
[snip regarding greenwashing and other]


May 27, 2020
On Wednesday, 27 May 2020 at 13:47:46 UTC, Claude wrote:
> On Wednesday, 27 May 2020 at 13:42:08 UTC, Andrej Mitrovic wrote:
>> Is the actual problem those `@trusted:` declarations at the top of C headers?
>>
>> There could be a simple solution to that:
>>
>> Ban `@trusted:` and `@trusted { }` which apply to multiple symbols. Only allow `@trusted` to apply to a single symbol. For
>
> IMO, it makes things worse. Because the careless programmer will slap @trusted to every declaration (maybe with a script or find/replace macro of his editor). So now, we don't know if the annotation is greenwashing or careful examination of the definition.

The difference is when adding new symbols. If version control is used, it would be very obvious in a review whether a new @trusted symbol was added or not. A diff typically shows several lines of context, and a toplevel `@trusted:` is easy to miss.
May 27, 2020
On Wednesday, 27 May 2020 at 05:49:49 UTC, Walter Bright wrote:
> [snip]
>
> Nothing at all.
>
> But I doubt there is much legacy non-compiling code around.

I cannot speak for all the code out there, but I know of at least one binding out there [1] that will need to get updated in light of this DIP.

I also put together a wrapper [2] that sits on top of that binding (many years ago and no idea if the wrapper still works (I see no reason why the binding wouldn't), so this probably does count as legacy code) and calls the binding functions with templates and no safety annotations. So theoretically, after the DIP is accepted and without any other changes, nlopt.d becomes @safe and the binding that calls it also becomes @safe and any user code that calls it becomes @safe.

***************************

On a separate note, the current definition of @safe is that you cannot call @system functions. This prevents calling unannotated extern(C) prototypes from @safe code.

Ignoring DIP 1028 for a second, would you consider changing the rules so unannotated extern(C) prototypes are @safe instead of @system without any other change? Just this change by itself would mean that @safe functions can call unannotated extern(C) prototypes. Obviously this by itself could be rejected for special casing. However, I think the underlying question is should they be safe (ignoring @safe) or not. An argument made previously is that they should be safe and thus @safe. However, I think the overwhelming belief is that they are not safe and thus should not be @safe by default.

From this perspective, you could think of the DIP as doing two things. 1) it makes unannotated extern(C) prototypes @safe instead of @system and 2) it makes all other unannotated functions @safe instead of @system. The big focus is clearly on #1. You can assume that most people agree with you on #2 and thus focus the debate on #1

So, do you think unannotated exten(C) prototypes safe? If you think they are safe, then there is no issue with making them @safe by default. However, if you do not think they are safe, then it raises serious concerns to make them @safe by default.

[1] https://github.com/DlangScience/nlopt/blob/master/source/nlopt.d
[2] https://github.com/jmh530/nloptd/blob/master/source/nloptd.d
May 27, 2020
I'm curious what the distribution looks like between whether people agree that extern(C) should be @safe, or @system. People that think it should be @trusted, vote @safe, it's pretty much the same thing.

 https://www.strawpoll.me/20184671
May 27, 2020
On Wednesday, 27 May 2020 at 10:51:54 UTC, Walter Bright wrote:
> [..]

I was reading Bastiaan's inspiring ideas about provable verification of @trusted and something occurred to me. If we are serious about safety, we should consider @trusted annotation on extern C harmful. It provides little value and might be misleading like a bad comment:
// only call once, second call leaks
void waitForClose(size_t msTimeout);
The implementation was rewritten long ago, no one bothered to remove the remark.
The trustworthiness of extern code can be assessed by audit. It can only be set in stone by additional tools. git can nail down the version of a verified function in the CMake list. The compiler can't know what we are linking against or what's loaded at runtime.
@trusted extern C is meaningless. Pre DIP1028 we had to put it in for @safe code to compile.
I'm not sure how @system fits into this. It gets outdated the same way @trusted does.