On Sunday, 24 May 2020 at 08:55:32 UTC, Walter Bright wrote:
I infer your position is the idea that putting @trusted on the declarations isn't greenwashing, while @safe is.

I can't see a practical difference between:

@safe extern (C) void whatevs(parameters);
@trusted extern (C) void whatevs(parameters);

Both require that whatevs() provide a safe interface. The difference between them is in the implementation of those functions, not the interface. Since the D compiler cannot see those implementations, they are immaterial to the compiler and user.

From my perspective, there is a clear difference in meaning between them: @safe means verified by the compiler (which as you mentioned can never be true for declarations where the code is not available, hence it always is a lie in that case) and @trusted means verified by the developer.

Whenever @trusted is slapped on _anything_, it is clear that extra caution is needed (in codereviews etc.) and as others have mentioned, it is easily searchable.

When I put @safe on a piece of code, my expectation is that it is actually verified by the compiler. If that is not possible, it should not compile.

The same reasoning also applies to the case where the annotations are not added by the developer explicitly and the defaults are used instead:

If the default is @safe and the code for an unannotated declaration is not available, it should not compile.

Making @trusted the default is not an option because as mentioned earlier, one of the points of @trusted is for it to be actually seen, which is not the case if it is the default, so I will not elaborate on that.

If @sytem is the default, there is no issue but of course the whole point of this DIP is to move away from that.

I understand that today it is possible to slap @safe on declarations without code without the compiler complaining but it really _should_ be an error in order to have a consistent meaning of @safe, @trusted and @system (@safe = compiler verified, @trusted = user verified, @system = not verified) also in the case of declarations where no code is available.

Let's assume this is indeed the way to go, then there are 2 possible solutions for this DIP regarding how to handle this:

1. Make declarations without code default to @system instead of @safe. This is what many here have been arguing for but as you mentioned several times, it has the drawback of adding special cases to the language. As a user, it does not seem that problematic though because the compiler can easily tell you what is going on when there is an issue (i.e. calling an unannotated declaration without code from a @safe function could result in compiler error message that explains why this does not work). But I admit that it is still a bit weird to have 2 different defaults. Additionally, explicitly annotating such declarations with @safe should be a compile error.

2. Make @safe the default for _all_ declarations but still make @safe on declarations without code a compile error (because the compiler cannot verify it). This means that annotating function declarations without code with @system or @trusted is now mandatory. This is what Timon has been arguing for if I understood him correctly.

3. There may be a third option if we introduce something like conditional safety but I do not completely understand that yet. This is what H.S. Theo has been suggesting.

Option 1 and 2 both have the „issue“ that people might „greenwash“ things by simply slapping @trusted: at the top of a file. But that can always be done anyways and at least it is explicit and searchable. As mentioned, using @trusted now has the meaning that it is user verified so it always needs extra caution.

Personally I prefer option 2 because it is a lot more consistent: There are no special cases.

Until now, I did not discuss whether or not all of this should apply only to extern(C) function declarations without code or all function declarations without code. This is because it is a separate point. Both are possible and have pros and cons:

If it applies to extern(C) function declarations without code only, then we can still have @safe extern(D) declarations. They are not verified by the compiler but you get linker errors instead because @safe is part of the mangling. The benefit is that you get more @safe code by default, the drawback is that it relies on linker errors instead of compiler errors and that it introduces a special case.

If it applies to all function declarations without code, also extern(D) function declarations without bodies need to be annotated with @trusted explicitly if they are @safe or @trusted. If they are @system, we still get linker errors due to name mangling. The benefit is that it is a very consistent solution, no special cases are needed. The drawback is that it requires more manual effort to add the additional annotations (but then, don't we want to encourage people to explicitly annotate things anyways...?).

Personally, I prefer the second option because of its simplicity. Also you mentioned somewhere that linker errors are not that helpful to the user and I couldn’t agree more. Also I personally don't use extern(D) function declarations without bodies a lot, so the drawback is negligible for me. Others' experiences might be different though.

Steven actually made a proposal regarding creating 2 different manglings for extern(C) functions that are implemented in D. Regardless of which of the solutions is taken, this could provide the same benefits that we have for extern(D) functions (linker errors if @safety does not match in the mangling). However, it sounds like a complicated solution (in an answer to him, you already mentioned that there might be technical difficulties regarding some object formats, debugging symbols, etc.) and I am not sure it's worth it. It also makes swapping out the libraries a bit weird: if you use an actual C library, it will always link but if swap to a library implemented in D, it only links if the @saftey mangling matches.


Coming back to the original point: I think it is really important that we give @safe, @trusted and @sytem their clear meaning (as explained above) also for declarations without bodies. In my opinion, we should choose the second option in both of the questions I presented.
            • R... Arine via Digitalmars-d-announce
            • R... ag0aep6g via Digitalmars-d-announce
  • Re: DIP1028 - Rationale... Walter Bright via Digitalmars-d-announce
    • Re: DIP1028 - Rati... Timon Gehr via Digitalmars-d-announce
      • Re: DIP1028 - ... Paolo Invernizzi via Digitalmars-d-announce
      • Re: DIP1028 - ... Walter Bright via Digitalmars-d-announce
        • Re: DIP102... Panke via Digitalmars-d-announce
          • Re: DI... Walter Bright via Digitalmars-d-announce
            • R... Stefan Koch via Digitalmars-d-announce
            • R... Joseph Rushton Wakeling via Digitalmars-d-announce
        • Re: DIP102... Johannes Loher via Digitalmars-d-announce
          • Re: DI... aliak via Digitalmars-d-announce
            • R... Johannes Loher via Digitalmars-d-announce
            • R... aliak via Digitalmars-d-announce
            • R... Johannes Loher via Digitalmars-d-announce
          • Re: DI... Steven Schveighoffer via Digitalmars-d-announce
          • Re: DI... Juraj Mojzis via Digitalmars-d-announce
        • Re: DIP102... ag0aep6g via Digitalmars-d-announce
        • Re: DIP102... Adam D. Ruppe via Digitalmars-d-announce
        • Re: DIP102... Timon Gehr via Digitalmars-d-announce
          • Re: DI... Johannes T via Digitalmars-d-announce

Reply via email to